angularJS实现聊天窗口中发送和接收信息时,将聊天记录窗口滑动条实时滑至底部

场景:在开发聊天消息界面的项目中,一个非常常见的场景就是在聊天窗口中发送和接收信息时,需要将聊天记录窗口滑动条实时滑至底部。本人参考git上面的一个插件(参考地址:https://github.com/Luegg/angularjs-scroll-glue),自己摸索着开发了一个指令。在使用该插件之后,本人感觉有不爽的地方,只要点击界面任何位置,它都会滑至底部。相对于scroll-glue插件,我简化了该插件的实现,只保留滑动至底部的功能,同时可以动态设置是否生效该插件。

完整的angularJS的指令实现如下:

'use strict';

angular.module('myApp')
  .directive('scrollToBottom', ['$parse', '$window', '$timeout', function ($parse, $window, $timeout) {

    function createActivationState($parse, attr, scope) {
      function unboundState(initValue) {
        var activated = initValue;
        return {
          getValue: function () {
            return activated;
          },
          setValue: function (value) {
            activated = value;
          }
        };
      }

      function oneWayBindingState(getter, scope) {
        return {
          getValue: function () {
            return getter(scope);
          },
          setValue: function () {
          }
        };
      }

      function twoWayBindingState(getter, setter, scope) {
        return {
          getValue: function () {
            return getter(scope);
          },
          setValue: function (value) {
            if (value !== getter(scope)) {
              scope.$apply(function () {
                setter(scope, value);
              });
            }
          }
        };
      }

      if (attr !== '') {
        var getter = $parse(attr);
        if (getter.assign !== undefined) {
          return twoWayBindingState(getter, getter.assign, scope);
        } else {
          return oneWayBindingState(getter, scope);
        }
      } else {
        return unboundState(true);
      }
    }

    return {
      priority: 1,
      restrict: 'A',
      link: function (scope, $el, attrs) {
        var el = $el[0],
          activationState = createActivationState($parse, attrs.scrollToBottom, scope);

        var bottom = {
          isAttached: function (el,isAttached) {
            return isAttached;
          },
          scroll: function (el) {
            el.scrollTop = el.scrollHeight;
          }
        };

        function scrollIfGlued() {
          if (activationState.getValue() && !bottom.isAttached(el, scope.isAttached)) {
            bottom.scroll(el);
          }
        }

        scope.$watch(scrollIfGlued);

        $timeout(scrollIfGlued, 0, false);

        $window.addEventListener('resize', scrollIfGlued, false);

        $el.bind('scroll', function () {
          activationState.setValue(bottom.isAttached(el,scope.isAttached));
        });
      }
    };
  }]);


使用方法:

1、在聊天窗口所在元素中配置指令

2、控制当前controller的作用域scope.isAttached的值,该值控制指令的生效和失效,当scope.isAttached === false时,指令生效;否则失效。

代码示例:

(1)静态页面代码

scroll-to-bottom="true" ng-mouseenter="unbindGlued()" id="chatWindow">
ng-repeat="item in conversationlist"> message-info="item" value="{{item}}">

/**
 * 当点击聊天记录窗口时,不让滚动条自动滚至底部
 * @type {boolean}
   */
//标示滚动条是否滑至底部
$scope.isAttached   = false;
$scope.unbindGlued = function(){
  $scope.isAttached   = true;
};
/**
 * 聊天记录窗口失去焦点时,让滚动条自动滚至底部
 * @type {boolean}
 */
$scope.bindGlued = function(){
  $scope.isAttached   = false;
};
在具体的聊天场景中,可以动态设置$scope.isAttached的值来控制滚动条滑至底部,比如接收和发送消息的时候,将$scope.isAttached 设为false,让指令生效;而当鼠标放在聊天窗口的时候,则将$scope.isAttached 设为false,如代码所示,此时可以防止当我们点击界面任何区域时,滚动条滑至底部。


欢迎大家有更好的方法提出来,大家一起交流!


你可能感兴趣的:(angularJS实现聊天窗口中发送和接收信息时,将聊天记录窗口滑动条实时滑至底部)