有一个HTML锚点列表,我需要添加事件侦听器,据我了解,当我将其作为参数提及时,它并不能接收数组。
尝试使用自调用代替其他功能,但是这样i
甚至在调试时也没有被监听。
for (var i=0; i < anc.length; i++) {
anc[i].addEventListener('mouseover', function(i,pop,tri) {
console.log('i=%i', i); // last value of loop
pop[i].style.display = 'initial';
tri[i].style.animation='anim_dpt_tr 0.4s ease-out forwards';
});
...
}
更有用的代码
var pop = document.querySelectorAll('#cities > li > a > .popup');
const anc = document.querySelectorAll('#cities > li > a');
var tri = document.getElementsByClassName('triangle-left');
for (var i=0; i < anc.length; i++) {
anc[i].addEventListener('mouseover', over(i, tri, pop));
anc[i].addEventListener('touchmove', over(i, tri, pop));
anc[i].addEventListener('touchend', out(i, tri, pop));
anc[i].addEventListener('mouseout', out(i, tri, pop));
}
function over(i,tri,pop) {
console.log("over_address=%i", pop[i]); // =0
pop[i].style.display = 'initial';
tri[i].style.animation='anim_dpt_tr 0.4s ease-out forwards';
}
function out(i,tri,pop) {
console.log("out_i=%i", i); // =each index
pop[i].style.display = 'none';
tri[i].style.animation='anim_dpt_tr_back 0.3s ease-in forwards';
}
此处是HTML树
<ul id="cities">
<li>
<a href="">Shoulder
<span class="triangle-left"></span> <span class="popup">Arm</span> </a>
</li>
...
如何将数组正确传递给事件处理程序?
答案 0 :(得分:3)
您的“更有用的代码”是错误的,因为它实际上并未分配任何事件处理程序;它只是立即调用代码并返回undefined
。
要采用这种方法,您需要让那些函数返回一个函数。在那定义事件参数。
function over(i,tri,pop) {
return function(event) {
console.log("over_address=%i", pop[i]); // =0
pop[i].style.display = 'initial';
tri[i].style.animation='anim_dpt_tr 0.4s ease-out forwards';
}
}
function out(i,tri,pop) {
return function(event) {
console.log("out_i=%i", i); // =each index
pop[i].style.display = 'none';
tri[i].style.animation='anim_dpt_tr_back 0.3s ease-in forwards';
}
}
这是一种古老的做法。最近,您可以使用i
或for
而不是let
,使用范围为const
循环块的var
变量。
要考虑的另一件事是,缓存集合是否真的值得。如果每个集合中每个i
元素之间的布局都存在非常简单的关系,则首选在处理程序内部进行DOM遍历。
另一种可能性是创建一个实现 EventListener 接口的对象。然后,您可以将每个元素分配给对象,并使用对象本身代替事件处理程序功能。
var pop = document.querySelectorAll('#cities > li > a > .popup');
const anc = document.querySelectorAll('#cities > li > a');
var tri = document.getElementsByClassName('triangle-left');
for (var i=0; i < anc.length; i++) {
// Create a new instance of your object, giving it the data needed
// when an event occurs.
var obj = new MyElements(pop[i], anc[i], tri[i], i);
// Use the object itself in lieu of an event handler function
// (see below)
anc[i].addEventListener("mouseover", obj);
anc[i].addEventListener("touchmove", obj);
anc[i].addEventListener("mouseout", obj);
anc[i].addEventListener("touchend", obj);
}
// Holds the relevant info for each index
function MyElements(pop, anc, tri, i) {
this.pop = pop
this.anc = anc
this.tri = tri
this.i = i
}
// Implements the EventListener interface.
// This is what gets invoked when an event occurs.
// It is set up to simply invoke a function on the same object
// that has been given the same name as the event.
MyElements.prototype.handleEvent = function(event) {
this[event.type](event)
}
// These are the functions for each event type. For simplicity, I
// gave each handler the name of the event that fires it so that
// you can use event.type to invoke them.
MyElements.prototype.mouseover =
MyElements.prototype.touchmove = function over(event) {
console.log("over_address=%i", this.i); // =0
this.pop.style.display = 'initial';
this.tri.style.animation='anim_dpt_tr 0.4s ease-out forwards';
}
MyElements.prototype.mouseout =
MyElements.prototype.touchend = function out(event) {
console.log("out_i=%i",this.i); // =each index
pop[i].style.display = 'none';
tri[i].style.animation='anim_dpt_tr_back 0.3s ease-in forwards';
}
答案 1 :(得分:0)
您可以使用.bind()完成此操作。您的所有通话可能看起来像,例如over.bind(null, i, tri, anc)
,用作函数处理程序时。注意,必需的null
作为第一个参数。
因此,它将转换为:
over.bind(null, i, tri, pop)
out.bind(null, i, tri, pop)
让我知道是否可行。否则,给我留言。
答案 2 :(得分:0)
此行anc[i].addEventListener('anyEvent', over(i, tri, pop))
将尝试立即调用该函数。相反,您可以创建一个回调函数并从中调用over
和out
。同样,除了传递多个参数外,还使用this
传递上下文。这里的this
是指触发事件的元素,在这种情况下为anchor tag
。
然后在over/out
函数内部使用elem.querySelector('.popup')
,它将以触发事件的元素内部具有popup
类的元素为目标。然后您可以添加样式属性
const anc = document.querySelectorAll('#cities > li > a');
for (var i = 0; i < anc.length; i++) {
anc[i].addEventListener('mouseover', function() {
over(this)
});
anc[i].addEventListener('mouseout', function() {
out(this)
});
}
function over(elem) {
elem.querySelector('.popup').style.display = 'initial';
elem.querySelector('.triangle-left').style.animation = 'anim_dpt_tr 0.4s ease-out forwards';
}
function out(elem) {
elem.querySelector('.popup').style.display = 'none';
elem.querySelector('.triangle-left').style.animation = 'anim_dpt_tr_back 0.3s ease-in forwards';
}
<ul id="cities">
<li>
<a href="">Shoulder
<span class="triangle-left"></span> <span class="popup">Arm</span> </a>
</li>
<li>
<a href="">Shoulder
<span class="triangle-left"></span> <span class="popup">Leg</span> </a>
</li>
<li>
<a href="">Shoulder
<span class="triangle-left"></span> <span class="popup">ercerc</span> </a>
</li>
</ul>