简体   繁体   English

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

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

I'm drawing a grid of boxes, want to be able to click on each box and send notification with its ID to server using SocketIO我正在绘制一个框格,希望能够单击每个框并使用 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});
    });
});

This works, I can click each box and event is sent to server, but apparently this does not allow the even listener to be removed, as per https://www.w3schools.com/jsref/met_element_removeeventlistener.asp这可行,我可以单击每个框并将事件发送到服务器,但显然这不允许删除偶数侦听器,根据https://www.w3schools.com/jsref/met_element_removeeventlistener.asp

Note: To remove event handlers, the function specified with the addEventListener() method must be an external function, Anonymous functions, like "element.removeEventListener("event", function(){ myScript });"注意:要删除事件处理程序,使用 addEventListener() 方法指定的 function 必须是外部 function,匿名函数,例如 "element.removeEventListener("event", function(){ myScript });" will not work.不管用。

So I changed to this所以我改成了这个

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});
}

Now as soon page is loaded into browser all boxes in grid are automatically 'clicked' and events sent to server.现在,一旦页面加载到浏览器中,网格中的所有框都会自动“单击”并将事件发送到服务器。

Can anyone help understand why this is happening?谁能帮助理解为什么会这样?

Can anyone help understand why this is happening?谁能帮助理解为什么会这样?

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

addEL(box.id) is function call therefore its taking id and executing it on each box's click listener attachment addEL(box.id)function 调用,因此它采用 id 并在每个框的点击侦听器附件上执行它

Solution:解决方案:

AddEventListener expects the event name and the callback function name or the function itself(inline function) AddEventListener需要事件名称和callback function namefunction本身(内联函数)

Just give the function name in the parameter.只需在参数中给出 function 名称即可。

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

Access the id of the box from event object like event.currentTarget.id从事件 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});
}

change改变

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

to

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

or simplier (be sure you can use ES6 here)或者更简单(确保你可以在这里使用 ES6)

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

or或者

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

it's because you use the result of the function, not the function itself这是因为您使用 function 的结果,而不是 function 本身

UPD: to be able to delete handler declare the function like var adder = addEL.bind(null, box.id) and use box.addEventListener('click', adder); UPD:为了能够删除处理程序声明 function 像var adder = addEL.bind(null, box.id)并使用box.addEventListener('click', adder);

also there can be an array of such functions like adders.push(addEL.bind(null, box.id)) , box.addEventListener('click', adders[i]);也可以有一个这样的函数数组adders.push(addEL.bind(null, box.id)) , box.addEventListener('click', adders[i]);

The code box.addEventListener('click', addEL(box.id));代码box.addEventListener('click', addEL(box.id)); calls addEL(box.id) and passes the result of that call to the second argument of addEventListener , that's why addEL is called directly without any event.调用addEL(box.id)并将调用的结果传递给addEventListener的第二个参数,这就是为什么直接调用addEL而没有任何事件。

if you want to be able to remove the listener then you need to write it that way:如果您希望能够删除侦听器,那么您需要这样编写:

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