手机版

JS奇怪技术使用滚动来监控调整大小

时间:2021-09-04 来源:互联网 编辑:宝哥软件园 浏览:

大家都知道原生的resize事件只能作用于defaultView,也就是window,那么我们应该如何监控其他元素的大小变化呢?最近,作者发现了一种通过滚动事件间接监控调整大小事件的神奇方法。本文将分析这种方法的原理并实现代码。

原则

首先,我们来看看卷轴事件是关于什么的。

当文档视图或元素被滚动时,触发滚动事件。

当文档视图或元素滚动时,滚动事件被触发。

也就是说元素滚动的时候会触发这个事件,那么元素什么时候滚动呢?当元素大于它的父元素并且父元素允许它滚动时,它可以滚动。换句话说,滚动意味着父元素和子元素的大小不一致,这是这个方法的核心。

然后,我们需要在元素大小发生变化的时候,改变scrollLeft或者scrollTop,从而触发滚动事件,进一步知道它的大小发生了变化。

聆听元素变得更大

当元素变大时,我们可以看到更多,其内部的可滚动区域会逐渐变小,但这不会改变滚动条的位置,但是当元素大到足以让滚动条消失时,就会让scrollLeft或者scrollTop变成0,所以我们知道元素变大了,所以我们只需要1px来判断,如下图:

听音元件变小了

当元素变小时,可滚动区域会变大,滚动条的位置不会改变。这里采用的方法是让可滚动区和父元素一起按一定比例缩小,让父元素挤压滚动区,从而间接改变滚动条scrollLeft或scrollTop的大小。文字描述可能不太清楚。让我们看看下图:

通过以上两种方式,我们可以得到resize事件。

实现

首先,为了不影响原始元素,我们应该创建一个与被监控元素一样大的元素,并对其进行相关操作。然后我们需要两个子元素来监控元素变大和元素变小的情况。因此,构建了以下HTML结构:

div class=' resize-triggers ' div class=' expand-trigger ' div/div/div div class=' contract-trigger '/div/div它们对应的CSS如下:resize-触发器{ visibility:隐藏;opa city 3360 0;}.调整触发器大小。调整触发器div的大小。content : { content : }之前的contract-trigger :display:块;绝对位置:top : 0;left : 0;高度: 100%;宽度: 100%;飞越:隐藏;}.resize-触发器div { overflow: auto}.{ width: 200%之前的contract-trigger :高度:200%;}的子元素的宽度和高度。expand-triggers应该保持比父元素大1px,并且两个触发器都应该保持在右下角的状态,因此我们可以实现以下状态重置函数,并在初始化和每个滚动事件期间调用它:

/* * *重置触发器* @param元素要处理的元素*/const重置触发器=function(element){ const trigger=element。_ _调整触发器的大小_ _;//要重置的触发器const expand=trigger . first element child;//第一个子元素用于监控放大的const contract=trigger . last telementchild;//最后一个子元素,用于监视收缩常量expandchild=expand . first element child;//第一个子元素的第一个子元素用于监控contract . scroll left=contract . scroll width;//滚动到最右边的contract . scroll top=contract . scroll height;//滚动到底部expandchild . style . width=expand . offsetwidth 1 ' px ';//保持宽度大于1px expandchild . style . height=expand . offsetheight 1 ' px ';//保持高度大于1 pxexpand . scroll left=expand . scroll width;//滚动到最右边expand . scroll top=expand . scroll height;//滚动到最右侧};我们可以使用以下函数来检测元素大小是否发生了变化:

/** * 检测触发器状态* @param元素要检查的元素* @返回{布尔值}是否改变了大小*/const CheckTriggers=function(element){//宽度或高度不一致就返回真实的返回元素。偏移为!==元素__resizeLast__ .width | | element.offsetHeight!==元素__resizeLast__ .身高;};最终,我们可以实现简单的事件监听的添加:

/** * 添加大小更改监听* @param元素要监听的元素* @param fn回调函数*/export const addResizeListener=function(element,fn){ if(isServer)return;//服务器端直接返回if (attachEvent) { //处理低版本ie元素。attach事件(' on resize ',fn);} else {if(!元素__resizeTrigger__) { //如果没有触发器if (getComputedStyle(元素)。位置===' static '){元素。风格。位置='相对';//将静电改为相对}创建样式();元素_ _ Resizelast _ _={ };//初始化触发器最后的状态元素_ _ ResizeListeners _ _=[];//初始化触发器的监听器const resizeTrigger=元素_ _ resizeTrigger _ _=文档。创建元素(' div ');//创建触发器resizetrigger类名=' resize-triggers ';resizetriggerinner html=' div class=' expand-trigger ' div/div/div class=' contract-trigger '/div ';元素。appendchild(resizeTrigger);//添加触发器resetTrigger(元素);//重置触发器元素。addeventlistener(' scroll ',scrollListener,true);//监听滚动事件/*收听钢性铸铁动画以检测元素显示/重新附加*///监听半铸钢钢性铸铁(铸造半钢)动画来检测元素显示或者重新添加if (animationStartEvent) { //动画开始resizetriggeraddeventlistener(animationStartEvent),function(event) { //增加动画开始的事件监听if(事件。ANIMATION NAME===RESIZE _ ANIMATION _ NAME){//如果是大小改变事件resetTrigger(元素);//重置触发器} });} }元素__resizeListeners__ .push(fn);//加入该回调}};以及如下的函数来移除事件监听:

/** * 移除大小改变的监听* @param元素被监听的元素* @param fn对应的回调函数*/export const removeResizeListener=function(element,fn) {if (attachEvent) { //处理ie元素。独立通风口('在调整大小时',fn);} else { element .__resizeListeners__ .拼接(元件__resizeListeners__ .indexOf(fn),1);//移除对应的回调函数if(!元素__resizeListeners__ .长度){ //如果全部时间被移除元素。removeeventlistener(' scroll ',scrollistener);//移除滚动监听元素__resizeTrigger__=!element.removeChild(元素_ _ ResizeTrigger _ _);//移除对应的触发器,但保存下来} }};其他

其中有部分内容是用来优化的,并不影响基础功能,如对服务器渲染、客户端渲染的区分,对工业管理学(工业工程)的特殊处理,以及通过不透明的动画来解决铬上的臭虫。

好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如有疑问大家可以留言交流,谢谢大家对我们的支持。

版权声明:JS奇怪技术使用滚动来监控调整大小是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。