【问题标题】:JavaScript addEventListener() external function triggering without the eventJavaScript addEventListener() 外部函数在没有事件的情况下触发
【发布时间】:2020-05-12 12:23:31
【问题描述】:

我正在绘制一个框格,希望能够单击每个框并使用 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() 方法指定的函数必须是外部函数, 匿名函数,例如 "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});
}

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

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

【问题讨论】:

    标签: javascript addeventlistener


    【解决方案1】:

    谁能帮助理解为什么会发生这种情况?

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

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

    解决方案:

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

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

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

    event.currentTarget.id这样的事件对象访问盒子的id

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

    【讨论】:

    • 谢谢,这让我可以做我想做的事。
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      改变

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

      这是因为你使用的是函数的结果,而不是函数本身

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

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

      【讨论】:

      • 那将如何解决but apparently this does not allow the even listener to be removed
      • 没有注意到这个通知。给答案写了 UPD
      猜你喜欢
      • 1970-01-01
      • 2010-10-10
      • 2019-02-27
      • 2018-08-04
      • 1970-01-01
      • 1970-01-01
      • 2012-12-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多