繁体   English   中英

JavaScript addEventListener() 外部 function 在没有事件的情况下触发

[英]JavaScript addEventListener() external function triggering without the event

我正在绘制一个框格,希望能够单击每个框并使用 SocketIO 向服务器发送带有其 ID 的通知

<body>
<div class="wrapper">
    <div id="1" class="box"></div>
    <div id="2" class="box"></div>
</div>
</body>

let boxes = document.querySelectorAll('.box');

Array.from(boxes, function(box) {
    box.addEventListener('click', function()  {
        id = box.id

        //Send socketio message to server
        socket.emit('box_event_client', {data: id});
    });
});

这可行,我可以单击每个框并将事件发送到服务器,但显然这不允许删除偶数侦听器,根据https://www.w3schools.com/jsref/met_element_removeeventlistener.asp

注意:要删除事件处理程序,使用 addEventListener() 方法指定的 function 必须是外部 function,匿名函数,例如 "element.removeEventListener("event", function(){ myScript });" 不管用。

所以我改成了这个

Array.from(boxes, function(box) {
    box.addEventListener('click', addEL(box.id));
});

function addEL(boxID) {
    console.log("Box clicked: " + boxID)

    //Send socketio message to server
    socket.emit('box', {data: boxID});
}

现在,一旦页面加载到浏览器中,网格中的所有框都会自动“单击”并将事件发送到服务器。

谁能帮助理解为什么会这样?

谁能帮助理解为什么会这样?

Array.from(boxes, function(box) {
    box.addEventListener('click', addEL(box.id));
});

addEL(box.id)function 调用,因此它采用 id 并在每个框的点击侦听器附件上执行它

解决方案:

AddEventListener需要事件名称和callback function namefunction本身(内联函数)

只需在参数中给出 function 名称即可。

Array.from(boxes, function(box) {
    box.addEventListener('click', addEL);
});

从事件 object 访问框的 id,如event.currentTarget.id

function addEL(event) {
    let boxId=event.currentTarget.id
    console.log("Box clicked: " + boxId)
    //Send socketio message to server
    socket.emit('box', {data: boxId});
}

改变

box.addEventListener('click', addEL(box.id));

box.addEventListener('click', function() { addEL(box.id) });

或者更简单(确保你可以在这里使用 ES6)

box.addEventListener('click', () => addEL(box.id));

或者

box.addEventListener('click', addEL.bind(null, box.id));

这是因为您使用 function 的结果,而不是 function 本身

UPD:为了能够删除处理程序声明 function 像var adder = addEL.bind(null, box.id)并使用box.addEventListener('click', adder);

也可以有一个这样的函数数组adders.push(addEL.bind(null, box.id)) , box.addEventListener('click', adders[i]);

代码box.addEventListener('click', addEL(box.id)); 调用addEL(box.id)并将调用的结果传递给addEventListener的第二个参数,这就是为什么直接调用addEL而没有任何事件。

如果您希望能够删除侦听器,那么您需要这样编写:

Array.from(boxes, function(box) {
    let clickCallback = function()  {
        id = box.id

        //Send socketio message to server
        socket.emit('box_event_client', {data: id});
    }

    box.addEventListener('click', clickCallback);

    // you can remove the listener within the scope where clickCallback is defined
    // box.removeEventListener('click', clickCallback);
});

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM