document.addEventListener versus $().on

Recently, I came across an odd behavior while trying to add event listeners to the document. Strangely, when adding listeners to HTMLElements, everything worked smoothly, but for some reason, adding a listener to the document did not have any effect. However, strangely enough, using jQuery made it work perfectly.

I am puzzled as to why these two functions are not functioning in the same way. Can anyone shed light on this discrepancy?

["customEvent1", "customEvent2"].forEach(
    (event: string) => {
        document.addEventListener(event, () => this.eventHandler());
    });

$(document).on("customEvent1 customEvent2", () => this.eventHandler());

EDIT: It appears that there may be some confusion about the setup:

  1. The function is contained within a class
  2. I am utilizing TypeScript/ES6
  3. The EventHandler is a class method
  4. The custom event is triggered with
    $(document).trigger("customEvent1")
    ;

Answer №1

When triggering a custom event in jQuery with

$(document).trigger("customEvent2");
, the library does not create a native event, but rather emulates the handling of it as explained in the source code (jquery src/event/trigger.js).

If you have registered an event handler using document.addEventListener, then trying to trigger those events with $(document).trigger( will not work.

However, if you manually create and dispatch an event using native JavaScript like this:

var event = new Event('customEvent1');
document.dispatchEvent(event);

You will be able to catch that event using both document.addEventListener and jQuery's .on method.

Answer №2

It seems like there is an issue with your arrow function in the code. You could simplify it by passing in the handler directly instead of using unnecessary syntax. Additionally, keep in mind that jQuery can only create event-like callbacks and not real events when triggering events registered with vanilla js.

function eventHandler() {
    console.log("custom event");
}

["customEvent1", "customEvent2"].forEach(
    event => document.addEventListener(event, eventHandler)
);

var event1 = new Event('customEvent1');
document.dispatchEvent(event1);

var event2 = new Event('customEvent2');
document.dispatchEvent(event2);

Remember that when triggering events registered with vanilla js using jQuery, you will need to use the trigger method as shown below:

// ok
document.addEventListener('customEvent1', eventHandler);
var event1 = new Event('customEvent1');
document.dispatchEvent(event1);

// ok
$(document).on("customEvent2", eventHandler);
$(document).trigger("customEvent2");

// ok
$(document).on("customEvent3", eventHandler);
var event3 = new Event('customEvent3');
document.dispatchEvent(event3);

// not okay
document.addEventListener('customEvent4', eventHandler);
$(document).trigger("customEvent4");

Answer №3

The issue does not lie in how you are adding event handlers. Both the use of addEventListener and the on method are correct. However, the problem may be related to either the forEach loop or the arrow functions that can alter the context of this. To make sure you are referencing the intended object, try updating your code as follows:

var self = this;
["customEvent1", "customEvent2"].forEach(
    (event) => {
        document.addEventListener(event, () => self.eventHandler());
    });

$(document).on("customEvent1 customEvent2", () => self.eventHandler());

The behavior of the this keyword can be a bit complex since it is bound by context.

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

The CSS classes for the dropzonejs are not being properly updated for editing purposes

I'm currently facing an issue where I am attempting to include an editable area inside a dropzone, but for some reason, the editable area is not visible within the dropzone and the CSS classes are not being applied. <a href="#" editable-text="us ...

Prevent repeating the same table header multiple times when generated dynamically with jQuery

I have an array called groups which contains name and regid. I want to display the name key as the column header of a table. To achieve this, I implemented the following code: var Name = v.name; var regId = v.regid; var rowStr = '<th d ...

Tips for fetching individual item information from Firebase real-time database using Angular 9 and displaying it in an HTML format

product.component.ts import { AngularFireDatabase } from '@angular/fire/database'; import { ProductService } from './../product.service'; import { ActivatedRoute } from '@angular/router'; import { Component, OnInit} from &apo ...

Difficulty paginating jqgrid when using an array as the data source

Encountering an issue with pagination in jqgrid while working with array data containing 18 records. Even after specifying pagination:true, pager:jQuery('#pager1'), the records are not displaying in pages. Can anyone assist me in implementing pag ...

Activate tooltip by clicking outside of the dropdown menu

I am experiencing an issue with a tooltip and a dropdown menu. Whenever I interact with the dropdown by clicking outside of it or inside its contents, the tooltip content is triggered again. For example, when I hover over the button, the tooltip triggers ...

InvalidAction: The function forEach cannot be applied to "res"

Here is the HTML code that I am currently working with: <div *ngIf="chart" class="col-xl-4 col-lg-6"> <div class="card cardColor mb-3"> <div class="card-header headColor"> <img class="img-fluid" src="../../../ ...

Is it more effective to utilize a filter or request fresh data when filling in a form's drop-down choices?

Utilizing an axios ajax request, I am retrieving a JSON list of tags related to a specific topic selected from a dropdown. If no topic is chosen, all tags in the database (approximately 100-200 tags) are fetched. The process involves: User selects a topi ...

Tips for customizing the font color in Material UI Typography

Is it possible to change the color of only this text to red? return <Typography style={{ color: 'red' }}>Login Invalid</Typography> I came across this online solution, but I am unsure how to implement it as there is no theme={color ...

Tips for handling an empty jQuery selection

Below is the code snippet: PHP CODE: if($data2_array[7]['status'] == "OK"){ $degtorad = 0.01745329; $radtodeg = 57.29577951; $dlong = ($lng - $supermercado_lng); $dvalue = (sin($lat * $degtorad) * sin($superm ...

Show additional information when a row in the Bootstrap Vue table is clicked

I am attempting to create a unique user experience by displaying row details when a row is clicked, rather than clicking on a button as described in the documentation. However, the documentation lacks specific instructions on how to implement this feature. ...

tips for preventing issues when the data array is empty

Here is the JSON data that I am dealing with: { "id": 43, "dataEvento": "2022-09-01T00:00:00.000+0000", "dataInvio": null, "idComunicazioneAssociata": null, "certificatoMedico" ...

Can you explain the significance of 1e9 in the context of NodeJS hrtime?

When the calculation multiplies by 1e9 and divides by 1e6, what is the significance of this operation? ...

Visual Studio Code's Intellisense is capable of detecting overloaded functions in JavaScript

What is the best way to create a JavaScript overload function that can be recognized by Visual Studio Code IntelliSense, and how can this be properly documented? A good example to reference is Jasmine's it() function shown below: function it(expecta ...

Verifying the presence of Angular loading Google (or other) APIs, or tips on preventing share buttons from disappearing

Having a bit of an issue here, actually, make that four issues, all related (or so I think). Tried using the google, twitter, whatsapp, and facebook API to add share buttons. They come nicely packaged and are easy to implement on the webpage, serving their ...

Exploring SVGO CLI: A guide to inspecting SVGs across various directories

Currently, I am utilizing the SVGO CLI script to transform some icons within my project. Specifically, these icons are located in two separate folders - assets/icons/dark-mode and assets/icons/light-mode. My goal is to navigate through both of these folder ...

Ways to ensure the text on my website scrolls into view as the user navig

Is there a way to have my text show up as I scroll? I came across this , but I'm interested in how it actually functions. I saw a similar inquiry before, but it doesn't make sense to me. Can someone please explain or provide some examples on how ...

Is there a way to automatically recalculate the "Total Price" when the input values are adjusted?

Whenever I add an item to the cart, it gets appended to the row in the shopping cart, and the price adjusts accordingly. However, I'm having trouble getting the price to adjust whenever I change the input values (input type: "number"). I can't se ...

Generating unique names based on input from users

We are working with an array containing names and an input field where users can enter a string to receive name suggestions. The array includes names like Alex and Anna, and when the user types "a," we want to suggest these names. Below is the code snippet ...

Guide to seamlessly incorporate a HTML template into your Angular 7 project

I'm currently in the process of integrating an HTML template into my Angular 7 project, and unfortunately, it does not seem to be functioning as expected. To start off, I have placed the template files under assets/template/.. and included the necess ...

JavaScript | Calculating total and separate scores by moving one div onto another div

I have a fun project in progress involving HTML and Javascript. It's a virtual zoo where you can drag and drop different animals into their designated cages. As you move the animals, the total count of animals in the zoo updates automatically with the ...