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

Sort the results by total count in Mongoose Express Node.js after grouping by id

I have a unique collection of items: { "_id": { "$oid": "5f54b3333367b91bd09f4485" }, "items": [ { "_id": 20, "name": "Turkish Coffee", "price": ...

Having trouble retrieving the data from the second child object in an object returned by an API call in a

Having trouble accessing the second child object of an object generated by an API response. The weather API in question can be found at . Refer to Display.js for a detailed explanation. App.js import React,{useState} from 'react'; import Navbar ...

The datetimepicker is not functioning properly

I'm experiencing an issue with the datetimepicker where it doesn't display a calendar when I click the icon. Interestingly, the Chrome browser isn't showing any errors in the development console. <script src="Scripts/jquery-2.1.1.min.js ...

"Did you come across `item()` as one of the methods within the array

While studying the book 'JavaScript and jQuery Interactive Front-End Web Development', I came across this interesting sentence: You can create an array using a different technique called an array constructor. This involves using the new keyword ...

Validate the checkbox with Vuelidate only when the specified property is set to true

I have a website login form where users may need to check a specific checkbox before logging in. Here is part of the Vue component code that handles this functionality: <script setup lang="ts"> import {ref, defineProps} from 'vue&a ...

Passing image source from parent component to child component in Vue.js

I encountered an issue where I stored the image file name in a variable within the parent component and passed it to the child component using props. However, despite this setup, the child element is not displaying the image as expected. Here is the data ...

Electronic circuit embedded within a material-textured text field offering multiline functionality

While experimenting with TagsInput, I came across this helpful snippet on codesandbox that you can check out here. The challenge I encountered is when there are numerous chips, they extend beyond the boundaries of the text field. My goal is to implement ...

Converting a table into div elements and subsequently reverting it back to its original table format

[STOP DOWNVOTING: NEW AND IMPROVED] Discovering a simple technique on stackoverflow to transform tables into divs has been quite enlightening. By assigning classes to each tag, such as: <table class="table"> the process of converting from table to ...

Detecting changes in URL hash using JavaScript - the ultimate guide

What is the most effective method for determining if a URL has changed in JavaScript? Some websites, such as GitHub, utilize AJAX to add page information after a # symbol in order to generate a distinct URL without having to refresh the page. How can one ...

Is there a way to ensure that the elements created by the select form are only generated once?

I have a JavaScript function that dynamically creates paragraph and input elements based on user selection in HTML. However, I am looking to optimize the code so that each element is only created once. Snippet of JavaScript code: function comFunction(sel ...

Utilize the id in AngularJS to bring attention to a specific row within a table

I am brand new to using angularjs. I currently have a table structured like this: HTML <table class="table table-striped" id="manageResumeTable"> <thead class="text-center text-info text-capitalize"> <th class="text-center col- ...

Grab the URL from React Router

I need assistance with writing a function that updates the current location to match the route of a clicked button. Currently, the code is returning the URL of the page where the button was clicked, not the path related to the button itself. Are there an ...

Is your Scrollmagic failing to function once your website is uploaded to the server?

My website incorporates Scrollmagic to dynamically load sections (changing opacity and adding movement) as users scroll through it. Everything functions perfectly fine when I preview the HTML file on my computer, but once I uploaded it to my hosting serv ...

javascript accessing all data in firebase real-time database using JavaScript the right way

Working with node.js, I am retrieving data from the firebase real-time database. However, the data is being returned in the following format: Data Retrieval Code import firebaseApp from '../config.js'; import { getDatabase, ref, onValue } from & ...

What changes can be made to the HTML structure to ensure that two form tags function separately?

Hey there! I'm currently tackling a web project that involves incorporating two form tags on one page, each with its own distinct purpose. Nevertheless, it appears that the inner form tag isn't behaving as it should. My suspicion is that this iss ...

Utilizing Material UI Pickers and Formik to efficiently handle Date, Time, and Second components

Currently, I am developing a React application with Formik that requires the utilization of date and time pickers. The app is being constructed using Material-UI and I have been exploring the possibilities provided by Material-UI Pickers at Given my relat ...

Employ AJAX to dynamically refresh the page whenever a new row is inserted into the table

Currently, I am in the midst of learning AJAX because it is necessary for a project I am working on. The aim is to refresh a feed in real-time whenever a new row is added to a MYSQL table. While I have successfully achieved this using node.js, my client&ap ...

How do you switch selection to "hold" mode using Javascript?

In my Markdown preview area, clicking on text will cause the preview area to switch to a markdown source editor automatically, with the cursor jumping to the position corresponding to where it was clicked. function onMouseDown(e) { const range = documen ...

What steps can I take to enhance the efficiency of this JavaScript DOM data manipulation algorithm?

Purpose I am working with a DOM that contains around 70 elements (divs with content). I have the need to move and toggle the display of these divs frequently and rapidly. Speed is crucial in this process. The trigger for moving and toggling these divs is ...

Struggling to make Vue.js transition effects function properly?

I'm having trouble getting a vue.js (version 1) transition to work. I copied the code from their official website, but it's not running the javascript console.logs! Vue.transition('fade', { css: false, enter: function ( ...