s94-web
Version:
常用的web工具方法封装---牧人与鱼
143 lines (135 loc) • 6.43 kB
JavaScript
import s94_web from "./s94_web.js";
var s94_Scroll = (function (global){
let document = global?.document;
if (!document) return console.error('缺少 document 对象!');
let Scroll = {
can_action: true,
Listener:[], //绑定事件集
/**
* 添加指定条件的文档滚动事件监听
* @param {Object} dom DOM元素必须
* @param {Object} offset 匹配偏移量,规则和绑定相同,不传入表示不验证
* @param {Object} callback 通过验证后执行的回调函数,this为当前DOM
* @param {Object} reverse 是否翻转|false
* @param {Object} repeat 是否重复执行|false
*/
on: function(dom, offset, callback, reverse, repeat){
if(typeof(offset) != 'object') offset = {x: false, y: offset};
offset.x = typeof(offset.x)=="undefined" ? false : evalStr(offset.x);
offset.y = typeof(offset.y)=="undefined" ? false : evalStr(offset.y);
var getOffset = {
x: new Function('d','return '+offset.x.toString()),
y: new Function('d','return '+offset.y.toString()),
}
Scroll.Listener.push({
dom : dom,
status : 1,
offset : offset,
getOffset: getOffset,
callback: callback,
reverse : !!reverse,
repeat : !!repeat
})
Scroll.action();
},
/**
* 移除指定条件的文档滚动事件监听
* @param {Object} dom DOM元素必须
* @param {Object} offset 匹配偏移量,规则和绑定相同,不传入表示不验证
* @param {Object} reverse 是否翻转|false
* @param {Object} repeat 是否重复执行|false
*/
off: function(dom, offset, reverse, repeat){
if(!dom) return;
if(typeof(offset) != 'object') offset = {x: false, y: offset};
offset.x = typeof(offset.x)=="undefined" ? false : evalStr(offset.x);
offset.y = typeof(offset.y)=="undefined" ? false : evalStr(offset.y);
for(var i = 0,row; i < Scroll.Listener.length;){
row = Scroll.Listener[i];
var in_offset = (offset.x === false || offset.x == row.offset.x) && (offset.y === false || offset.y == row.offset.y);
var eq_reverse = typeof(reverse)=="undefined" || row.reverse == !!reverse;
var eq_repeat = typeof(repeat)=="undefined" || row.repeat == !!repeat;
if(row.dom === dom && in_offset && eq_reverse && eq_repeat){
Scroll.Listener.splice(i, 1);
}else{
i++
}
}
},
action: function(){
if(!Scroll.can_action || !Scroll.Listener.length) return;
//浏览器默认回滚,所以延迟执行
Scroll.can_action = false;
requestAnimFrame(function(){
//单位参数
var size = {vw: global.innerWidth, vh: global.innerHeight, rem: parseFloat(global.getComputedStyle(document.documentElement)['font-size'])};
for(var i = 0,row; i < Scroll.Listener.length;i++){
row = Scroll.Listener[i];
if(!inDocument(row.dom)) continue;
size.mw = row.dom.offsetWidth;
size.mh = row.dom.offsetHeight;
var offset = s94_web.domOffsetScreen(row.dom);
var to_offset = {
x: row.getOffset.x(size),
y: row.getOffset.y(size),
};
if(row.reverse) {//翻转
var in_offset = (to_offset.x === false || offset.x > to_offset.x) && (to_offset.y === false || offset.y > to_offset.y);
}else {
var in_offset = (to_offset.x === false || offset.x < to_offset.x) && (to_offset.y === false || offset.y < to_offset.y);
}
if(in_offset){
if(row.status){
if(!row.repeat) row.status = 0
row.callback.call(row.dom);
}
}else{
row.status = 1;
}
}
Scroll.can_action = true;
})
}
};
function evalStr(str){
return str===false || typeof(str)=="undefined" ? false : str.toString()
.replace(/([\d\.]+)vw/, '($1/100*d.vw)')
.replace(/([\d\.]+)vh/, '($1/100*d.vh)')
.replace(/([\d\.]+)mw/, '($1/100*d.mw)')
.replace(/([\d\.]+)mh/, '($1/100*d.mh)')
.replace(/([\d\.]+)rem/, '($1*d.rem)')
.replace(/(\d+)px/, '$1');
}
var requestAnimFrame = (function(){
return global.requestAnimationFrame || global.webkitRequestAnimationFrame || global.mozRequestAnimationFrame || function(){
if(typeof(arguments[0]) == 'function'){
global.setTimeout(arguments[0], 1000 / 60);
}
};
})();
function inDocument(dom){
s94_web(dom).addClass(inDocument.className);
var res = !!document.querySelector('.'+inDocument.className);
s94_web(dom).removeClass(inDocument.className);
return res;
}
inDocument.className = 'inDocument'+(new Date()).getTime();
document.addEventListener('scroll', function (){Scroll.action();}); //网页滚动时自动触发action
s94_web.dom.extend({
scrollOn: function(offset, callback, reverse, repeat){
this.forEach(function(dom){
Scroll.on(dom, offset, callback, reverse, repeat)
})
},
scrollOff: function(offset, reverse){
this.forEach(function(dom){
Scroll.off(dom, offset, reverse)
})
}
})
return Scroll;
})(typeof globalThis !== 'undefined' ? globalThis :
typeof self !== "undefined" ? self :
typeof window !== "undefined" ? window :
typeof global !== "undefined" ? global : {});
export default s94_Scroll;