JS奇技之利用滚动来监听调整详解

  

  

大家都知道知道原生的调整事件只能作用于defaultView即窗口上,那么我们应该通过什么样的方式来监听其他元素的大小改变呢?笔者最近学习发现了一种神奇的方法,通过滚动事件来间接实现调整事件的监听,本文将对这种方式进行原理的剖析与代码实现。

  

  

首先,我们先来看一下滚动事件是干嘛的。

  

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

  

当文档视图或者元素滚动的时候会触发滚动事件。
  

  

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

  

那么我们需要让元素大小发生改变时,使得scrollLeft或者scrollTop发生改变,从而触发滚动事件,进一步得知其大小发生了改变。

  

  

元素变大的时候,我们可以看到更多,其内部可滚动区域将慢慢减小,但这并不会造成滚动条位置的改变,但当元素大到让滚动条消失的时候会让scrollLeft或者scrollTop变成0,这样我们就知道了元素变大了,因此我们其实只需要1 px来判断,其图示如下:
  

  

 JS奇技之利用滚动来监听调整详解

  

  

当元素变小的时候,可滚动区域会变大,滚动条的位置其实并不会进行改变,这里采取的做法是,让可滚动区域和父元素成一定的比例一起缩小,让父元素来挤压滚动区域,从而间接改变滚动条scrollLeft或者scrollTop的大小,文字描述可能不是很清楚,我们看下图:

  

 JS奇技之利用滚动来监听调整详解

  

通过以上两种方式,我们可以就可以获得调整事件。

  

  

首先,为了不影响原有的元素,我们应当创建一个和要监听元素等大的元素,并对其进行相关操作,然后我们需要两个子元素来分别监听元素变大和元素变小两个情况。因此构造如下的HTML结构:

        & lt; div类=皉esize-triggers”比;   & lt; div类=癳xpand-trigger”比;   & lt; div> & lt;/div>   & lt;/div>   & lt; div类=" contract-trigger "祝辞& lt;/div>   & lt;/div>      

他们对应的CSS如下:

        .resize-triggers {   可见性:隐藏;   透明度:0;   }      .resize-triggers,   .resize-triggers祝辞div,   .contract-trigger:{之前   内容:“”;   显示:块;   位置:绝对的;   上图:0;   左:0;   高度:100%;   宽度:100%;   溢出:隐藏;   }      .resize-triggers祝辞div {   溢出:汽车;   }      .contract-triggers:{之前   宽度:200%;   高度:200%;   }      

其中<代码> .expand-triggers>      /* *   *重置触发器   * @param元素要处理的元素   */const resetTrigger=function(元素){   const触发=element.__resizeTrigger__;//要重置的触发器   const扩大=trigger.firstElementChild;//第一个子元素,用来监听变大   const合同=trigger.lastElementChild;//最后一个子元素,用来监听变小   const expandChild=expand.firstElementChild;//第一个子元素的第一个子元素,用来监听变大      合同。scrollLeft=contract.scrollWidth;//滚动到最右   合同。scrollTop=contract.scrollHeight;//滚动到最下   expandChild.style。宽度=扩张。offsetWidth + 1 +“px”;//保持宽度多1 px   expandChild.style。身高=扩张。offsetHeight + 1 +“px”;//保持高度多1 px   扩大。scrollLeft=expand.scrollWidth;//滚动到最右   扩大。scrollTop=expand.scrollHeight;//滚动到最右   };      

我们可以用如下函数检测元素大小是否发生了改变:

     /* *   *检测触发器状态   * @param元素要检查的元素   * @returns{布尔}是否改变了大小   */const checkTriggers=function(元素){//宽度或高度不一致就返回现实   返回元素。offsetWidth !==element.__resizeLast__。宽度| |元素。offsetHeight !==element.__resizeLast__.height;   

JS奇技之利用滚动来监听调整详解