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、在聊天窗口所在元素中配置指令

<div scroll-to-bottom="true" ></div>

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

代码示例:

(1)静态页面代码

<div scroll-to-bottom="true" ng-mouseenter="unbindGlued()" id="chatWindow">
  <!--聊天记录-->
  <div ng-repeat="item in conversationlist">
    <chat-message message-info="item" value="{{item}}"></chat-message>
  </div>
</div>

/**
 * 当点击聊天记录窗口时,不让滚动条自动滚至底部
 * @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,如代码所示,此时可以防止当我们点击界面任何区域时,滚动条滑至底部。


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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值