0

我正在使用 AngularJS 构建一个类似控制台的应用程序。我的要求之一是包含控制台的 div 会自动向下滚动。我使用监控内容并相应调整scrollTopdiv 属性的指令实现了这一点:

app.directive('autoScroll', function () {
    return {
        restrict: 'A',
        link: function (scope, element, attrs, ctrls) {
            var scrollToBottom = function () {
                element[0].scrollTop = element[0].scrollHeight;
            };
            scope.$watchCollection('outputLines', scrollToBottom);
        }
    };
});

第一种显示行的方法是ng-repeat结合使用无序列表和大括号语法进行绑定:

<div auto-scroll id="withHtml" class="list">
    <ul>
        <li ng-repeat="line in outputLines">{{line.text}}</li>
        <li>>> {{currentInput}}</li>
    </ul>
</div>

正如您在这个小提琴的绿色输出区域中看到的那样,这非常有效。输入行(以开头的行>>始终可见。

在此处输入图像描述

但其中一项要求也是在输出行中呈现 HTML。因此,我开始使用 ngSanitize 模块并从大括号语法切换到使用ng-bind-html指令:

<div auto-scroll id="withHtml" class="list">
    <ul>
        <li ng-repeat="line in outputLines" ng-bind-html="line.text"></li>
        <li>>> {{currentInput}}</li>
    </ul>
</div>

这导致输入行总是移出可见区域。正如您在上面提到的小提琴中的红色输出区域中看到的那样:

在此处输入图像描述

在这两种情况下,生成的输出看起来都一样。所以这是我的问题:为什么滚动行为会根据我使用大括号语法还是 ng-bind-html 指令而有所不同?

4

1 回答 1

2

这是一个时间问题。

如果您执行以下操作:

var scrollToBottom = function () {
  console.log(element[0].scrollHeight);
  element[0].scrollTop = element[0].scrollHeight;
};

您会注意到,经过几次输入后scrollHeight,设置的时间scrollTop会有所不同。

我还没有深入研究源代码以查看导致此问题的原因,但是您可以使用$evalAsync它来确保代码在 Angular 操作 DOM 之后但在浏览器呈现之前运行:

var scrollToBottom = function() {
  scope.$evalAsync(function() {
    element[0].scrollTop = element[0].scrollHeight;
  });
};

演示:http: //jsfiddle.net/cBny9/

于 2014-05-14T12:21:57.417 回答