Executing JavaScript's addEventListener() function without specifying the event that triggers it

I am currently working on creating a grid of boxes that can be clicked, sending notifications with their respective IDs to the server using SocketIO.

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

Although this method works and allows me to click on each box and send events to the server, I encountered an issue where the event listeners could not be removed. I found out from 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 });" will not work.

To address this problem, I made some changes:

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

However, after loading the page into the browser, all boxes in the grid are automatically 'clicked' and events are sent to the server. Can someone provide insight into why this is happening?

Answer №1

Could someone please assist me in understanding why this issue is occurring?

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

addEL(box.id) is a function call, which means it takes the id and executes it on each box's click event listener.

Solution:

AddEventListener requires the event name and the callback function name or the function itself (inline function).

Simply provide the function name as the parameter.

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

You can access the id of the box from the event object like 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});
}

Answer №2

When the code

box.addEventListener('click', addEL(box.id));
is executed, it invokes addEL(box.id) and passes the result of that invocation as the second argument to addEventListener. This is why addEL is called directly without waiting for any event.

If you wish to remove the listener later on, here is how you should write the code:

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

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

    box.addEventListener('click', clickCallback);

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

Answer №3

modify

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

to

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

or make it simpler (utilize ES6)

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

or

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

this change is necessary because you are using the result of the function, not the function itself

UPD: to be able to remove the handler, declare the function as

var eventHandler = useEventListener.bind(null, box.id)
and use
box.addEventListener('click', eventHandler);

you can also have an array of such functions like

eventHandlers.push(useEventListener.bind(null, box.id))
,
box.addEventListener('click', eventHandlers[i]);

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Is it possible to obtain the output of a JavaScript file directly? (kind of like AJAX)

My previous experience with AJAX involved a server-side language like PHP generating xHTML with attached JS. The JS would then query another file using parameters set in either GET or POST. The output of the queried file would be returned to the JS, which ...

The Node.js express-generator application encounters a problem and is unable to start because of a TypeError: app.set function is not recognized

During the setup of my application using nodejs and express-generator, I encountered an issue when running the following commands in my terminal: npm install multer --save npm audit fix Afterwards, when I attempted to run node ./bin/www I received an err ...

Tips for effectively creating and appending elements using JavaScript

Code Sample var result=$.getJSON("http://search.twitter.com/search.json?callback=?",{q:query}, function(data) { ... question. }); Query: In order to display each tweet result, I want to ...

Encountering an NPM error while attempting to initiate a new React application

Having trouble creating a React app due to an npm warning message? Seek assistance, please! npm WARN deprecated <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="19342d2e6a6867687c4b">[email protected]</a>: This ve ...

Exploring the functionality of Material-UI's TextField component through role-based testing with React

I currently have some components that contain mui TextFields, and there are two specific scenarios for these components: One TextField is meant for LicenseCode and does not require a label. Additionally, there are several TextFields generated using t ...

Substitute placeholders in array with information using a loop

I have a question regarding implementing an autosort feature in JavaScript. I want my page to automatically sort data rows based on different time intervals selected by the user through checkboxes. The data updates every 3 seconds, and the autosort functio ...

Increase the options available in the dropdown menu by adding more selected items, without removing any already selected

I came across this code on the internet http://jsfiddle.net/bvotcode/owhq5jat/ When I select a new item, the old item is replaced by the new item. How can I add more items without replacing them when I click "dropdown list"? Thank you <select id=&qu ...

What are the steps for importing KnockOut 4 in TypeScript?

It appears straightforward since the same code functions well in a simple JS file and provides autocompletion for the ko variable's members. Here is the TypeScript code snippet: // both of the following import lines result in: `ko` undefined // impo ...

Creating Component Variants for Google Optimize A/B testing in Next.js

I've been attempting to create a component variant in Google Optimize beyond just text or color changes, but I haven't found a suitable method to do so yet. I'm looking for guidance on how to integrate/configure Optimize with my code in orde ...

Reposition the span element to the right of the div tag

I need help adjusting the positioning of the elements in this HTML code. How can I move the span element with the image to the right of the div tag? Here is the code snippet: <div style='width:600px;padding-top: 2px;padding-bottom: 1px'& ...

I aim to design a unique child window specifically for an "about" section within an electron js application on the Windows platform

I am looking to create a child browser window to showcase some key points about my application. According to the Electron JS documentation, it supports the "about" role for Mac OS but does not have built-in support for Windows. Therefore, I am in the pro ...

Accessing JSON data in Node.js can be accomplished using various methods. By leveraging

Currently, I am attempting to retrieve data from a JSON file using nodeJS However, upon running the code, I encounter the following error message: TypeError: Cannot read property 'postcode' of undefined. Any ideas on how to resolve this issue? ...

How can I efficiently retrieve the name variable of a Quasar (or Vue 3) application?

Is there a way to incorporate something similar in Quasar without having to redefine the variable in every component? <template> <div>Enjoy your time at {{ APP_NAME }}.</div> </template> During the setup of my app with Quasar C ...

Is there a way to utilize localStorage to retain a classlist toggle status for a light/dark mode theme switch on the browser?

I am currently working on a portfolio website that features a light/dark mode theme switch. The functionality of the switch is working properly, but it doesn't save the user's preference when they refresh the page or navigate to another section. ...

Looking for a way to make one image disappear briefly while transitioning to another image in Javascript

**Hey there, coding enthusiasts! I could really use some help right now. I am trying to create a smooth image transition effect using Javascript, where one image fades out while the next one fades in seamlessly. As someone who is still relatively new to pr ...

JavaScript Async Ordering

I have a specific question regarding asynchronous operations in Javascript. I am currently building a Node.js API to interact with an OrientDB database, using the Node-orient package for basic connectivity functions. Some of these functions are as follows: ...

jQuery fieldset.change is a feature that allows you to manipulate

I'm looking to update the value of a button when a radio button is clicked. <fieldset id="product-color"> <input type="radio" id="red" name="color" value="Red"> <label for="red">Red</label><br> <input typ ...

Nested arrays in the JavaScript programming language

Is this JavaScript code accurate: var options = []; options.push(["Tom","Smith"]); options.push(["Mary","Jones"]); where each item in options is a two-element array of strings. I plan to add items to options using a for loop. Furthermore, can I i ...

Adjust the header image as you scroll

Currently, I have a static image in the header of the page. I'm looking to have the image change to a different one when half the page has been scrolled. Do I need to utilize JavaScript for this functionality or is it achievable with CSS alone? bo ...

What are the troubleshooting tools available in Electron for detecting errors and debugging issues?

What is the process for accessing error messages and console logs in Electron while developing? Can the logs be saved directly to a file as well? Edit: Similar to how error messages and console logs are shown in Chrome's dev tools, but within Electro ...