我怎样才能将多个'滚动'事件的fns合并成一个用于多个元素和不同参数(执行相同任务)的事件?

问题描述 投票:0回答:1

我在一个页面上有X个元素,当它们在一定数量的视口内时,每个元素都会做同样的事情(比如本例中的2倍)。

目前,我有一些逻辑语句来调用每个事件监听器fn。

if(!!document.getElementById('foo1'))window.addEventListener('scroll', listenerFoo1);
if(!!document.getElementById('foo2'))window.addEventListener('scroll', listenerFoo2);
if(!!document.getElementById('foo3'))window.addEventListener('scroll', listenerFoo3);
if(!!document.getElementById('foo4'))window.addEventListener('scroll', listenerFoo4);
//etc...

这些语句中的每一个 listenerFooX 函数检查元素何时在2个视口内,然后执行代码,后面是一个 window.removeEventListener 调用来结束它。

但是把这些基本重复的函数都写出来,会占用很多空间,让人感觉文件超级臃肿。我唯一能想到的就是做下面这样的事情。

document.getElementById('foo1').addEventListener('scroll', function(){
    listenerGroupFn('foo1','bar1',var1a,var1b);
});
document.getElementById('foo2').addEventListener('scroll', function(){
        listenerGroupFn('foo2','bar2',var2a,var2b);
    });
//etc...

当然,这样做是行不通的,因为那些listenerGroupFn从来没有运行过。

我想过给这个匿名函数取个名字叫 var listenerGroupFn = function() { ... } 但这也无济于事,因为到最后当我做了 removeEventListener 由于函数名是只读的,所以我不能在为每个事件输入函数后更改名称。

我很困惑如何去做这件事.下面是总结。

  1. 我有几十个元素,当它们在in view的X个视口内滚动时,它们会做同样的事情(每个元素有不同的参数)。
  2. 我有几十个单独的 "元素",这些元素在in view的X视口内滚动时做同样的事情(每个元素的参数不同)。listenerFoo# 函数,这些函数在我的文件中占据了很大的空间。
  3. 我试图将这些整合成一个函数,每个元素都会被调用,但可以通过滚动条分别结束。removeEventListener而不结束其他所有的事件,这就是我被卡住的地方。

    页面加载,所有事件监听器激活

    卷轴

    foo1进入视图,执行fn并结束事件监听器,但不结束所有其他foo23等事件。

    卷轴

    foo2进入视图,执行fn并结束事件监听器,但不结束所有其他foo34等事件。

---编辑---

增加一个基本概念的片段。

if(!!document.getElementById('foo1'))window.addEventListener('scroll', foo1Scr);
if(!!document.getElementById('foo2'))window.addEventListener('scroll', foo2Scr);
if(!!document.getElementById('foo3'))window.addEventListener('scroll', foo3Scr);
if(!!document.getElementById('foo4'))window.addEventListener('scroll', foo4Scr);
if(!!document.getElementById('foo5'))window.addEventListener('scroll', foo5Scr);
function foo1Scr(){
	if (document.getElementById('foo1').getBoundingClientRect().top <= (window.innerHeight*1.5)){
  	//do things
    console.log('1');
    window.removeEventListener('scroll',foo1Scr);
  }
}
function foo2Scr(){
	if (document.getElementById('foo2').getBoundingClientRect().top <= (window.innerHeight*1.5)){
    //do things
    console.log('2');
    window.removeEventListener('scroll',foo2Scr);
  }
}
function foo3Scr(){
	if (document.getElementById('foo3').getBoundingClientRect().top <= (window.innerHeight*1.5)){
    //do things
    console.log('3');
    window.removeEventListener('scroll',foo3Scr);
  }
}
function foo4Scr(){
	if (document.getElementById('foo4').getBoundingClientRect().top <= (window.innerHeight*1.5)){
  	//do things
    console.log('4');
    window.removeEventListener('scroll',foo4Scr);
  }
}
function foo5Scr(){
	if (document.getElementById('foo5').getBoundingClientRect().top <= (window.innerHeight*1.5)){
  	//do things
    console.log('5');
    window.removeEventListener('scroll',foo5Scr);
  }
}
<div style='height:1000px;width:200px;background-color:blue;'></div>
<div id='foo1' style='width:300px;height:250px;background-color:lightgreen;'>
</div>
<div style='height:1000px;width:200px;background-color:blue;'></div>
<div id='foo2' style='width:300px;height:250px;background-color:lightgreen;'>
</div>
<div style='height:1000px;width:200px;background-color:blue;'></div>
<div id='foo3' style='width:300px;height:250px;background-color:lightgreen;'>
</div>
<div style='height:1000px;width:200px;background-color:blue;'></div>
<div id='foo4' style='width:300px;height:250px;background-color:lightgreen;'>
</div>
<div style='height:1000px;width:200px;background-color:blue;'></div>
<div id='foo5' style='width:300px;height:250px;background-color:lightgreen;'>
</div>
javascript scroll dom-events event-listener
1个回答
0
投票

我认为你应该改变触发的条件。appear 事件,而不是在循环中记录和中断尚未出现的块,并在下一个事件中继续形成。

fooElms[i].getBoundingClientRect().top <= window.innerHeight*1.5

相反,你可以在尚未出现的区块处记录和中断,并在下一个区块处继续形成它。scroll否则 fooScr() 将发射 appear 事件连续事件块已经显示。

一旦达到发射条件 appear 事件是正确的,它不需要 removeEventListener.

好了,看看下面的代码吧。

var foos = ['foo1', 'foo2', 'foo3', 'foo4', 'foo5'];
var fooElms = foos.map( function(foo) {
  let elem = document.getElementById(foo);
  elem.addEventListener('appear', fooXScr);
  return elem;
} );

function fooXScr(ev) {
  let elem = ev.currentTarget;
  console.log(elem.id);
  /* Do something according to specific elem.id */
  elem.removeEventListener('appear',fooXScr);
}

window.addEventListener('scroll', fooScr);
function fooScr() {
  for (var i=0; i<fooElms.length; i++) {
    if (fooElms[i].getBoundingClientRect().top <= window.innerHeight*1.5) {
      var ev = document.createEvent('Event');
      ev.initEvent('appear', true, true);
      fooElms[i].dispatchEvent(ev);
      // console.log('fire event to elem:' + fooElms[i].id);
    }
  }
}
<div style='height:1000px;width:200px;background-color:blue;'></div>
<div id='foo1' style='width:300px;height:250px;background-color:lightgreen;'>
</div>
<div style='height:1000px;width:200px;background-color:blue;'></div>
<div id='foo2' style='width:300px;height:250px;background-color:lightgreen;'>
</div>
<div style='height:1000px;width:200px;background-color:blue;'></div>
<div id='foo3' style='width:300px;height:250px;background-color:lightgreen;'>
</div>
<div style='height:1000px;width:200px;background-color:blue;'></div>
<div id='foo4' style='width:300px;height:250px;background-color:lightgreen;'>
</div>
<div style='height:1000px;width:200px;background-color:blue;'></div>
<div id='foo5' style='width:300px;height:250px;background-color:lightgreen;'>
</div>
© www.soinside.com 2019 - 2024. All rights reserved.