基于window滚动事件来实时更新DOM的视图状态,以表明是否在规定的可视区,并

时间:2022-06-01 19:58:04

/* * * 扩展jq原型: 懒、懒加载、懒动画 * --- 基于window滚动事件来实时更新DOM的视图状态,以表明是否在规定的可视区,,并作有change回调 * * $jq.viewChange( {top:100,bottom:100,change:function(status){}} ) --- status: ‘in‘/‘out‘ * $jq.viewChange(‘off‘) * * $jq[n].viewChange.status = ‘in‘/‘out‘ ----- 状态为‘in‘表示该DOM在规定的可视区 * */ (function() { var $win = $(window); var winH = $win.height(); var _isRun = true; $win.resize(function() { winH = $win.height(); if (_isRun) { _isRun = false; setTimeout(function() { $win.trigger(‘scroll.viewChange‘); _isRun = true; }, 100); } }); var setStatus = function(params) { if (this.parentElement) { //判断DOM是否还在页面中 var $self = $(this); var offsetTop = $self.offset().top, selfH = $self.height(), scrollTop = $win.scrollTop(); if (scrollTop + winH + params.bottom > offsetTop && scrollTop - params.top < offsetTop + selfH) { if (this.viewChange.status !== ‘in‘) { this.viewChange.status = ‘in‘; params.change.call(this, this.viewChange.status); } } else { if (this.viewChange.status !== ‘out‘) { this.viewChange.status = ‘out‘; params.change.call(this, this.viewChange.status); } } } else { $win.off(‘scroll.‘ + this.viewChange.eventNamespace); } }; $.fn.viewChange = function(options) { if (options === ‘off‘) { this.each(function() { if (this.viewChange) { $win.off(‘scroll.‘ + this.viewChange.eventNamespace); delete this.viewChange; } }); } else { var params = { top: 0, //增加或缩小顶部范围 bottom: 0, //增加或缩小底部范围 change: $.noop //视图状态发生改变时的回调:function(status){} }; params = $.extend(params, options); params.top = parseInt(params.top); params.bottom = parseInt(params.bottom); this.each(function() { if (this.viewChange) { $win.off(‘scroll.‘ + this.viewChange.eventNamespace); } this.viewChange = { eventNamespace: ‘viewChange.‘ + Math.random().toString().replace(‘0.‘, ‘‘), }; $win.on(‘scroll.‘ + this.viewChange.eventNamespace, function() { setStatus.call(this, params); }.bind(this)); setStatus.call(this, params); }); } return this; }; })(); //使用情况 $jq.viewChange({ top: -100, //缩小顶部范围 bottom: 100, //增加底部范围 change: function(status) { if (status === ‘in‘) { //当滚动到规定的可视区时 } else if (status === ‘out‘) { //当滚动出规定的可视区时 } } });