Creating and using custom events

6

Searching found Event and CustumEvent , both can be used to create events, and to control subscriptions, removals and issues of the event you should use EventTarget , but I did not understand how they work, for example, like me could you create a custom click event?

//Cria um evento de clique personalizado
const myClick = new Event('myClick');

//Alguma coisa para guardar as chamadas de "addEventListener"

//Adiciona um ouvinte do evento personalizado aos elmentos
myElement.addEventListener('myClick', event => console.log(event));
myOtherElement.addEventListener('myClick', event => console.log(event));

//Quando houver um clique na tela
window.addEventListener('click', function(event) {
    //Percorre uma lista onde ficaria armazenado os elementos que foram adicionado ouvintes do evento
    for(element of elementList) {
        //Se o elemento for igual ao elemento principal do clique na janela
        if (event.target === element) {
            //Dispara o evento customizado de clique
            element.dispatchEvent(myClick);
        }
    }
});

Am I on the right track? How do I save calls to addEventListener ?

The example is exactly the same as the click event that already exists, it's just an example. At the moment I just want to know how to do it in modern browsers, I'm not worried about compatibility

    
asked by anonymous 23.09.2018 / 03:02

4 answers

13

Basically, to create a custom event and listen to it, you should:

  • Create the event using new Event('eventName') ;
  • Trigger the event using .dispatchEvent(event) ;
  • Listen to the event using .addEventListener() .
  • The example below shows the whole process:

    // Para criar o evento:
    const myClickEvent = new Event('myClick');
    
    const myDiv = document.querySelector('#my-div');
    
    // Para ouvir o evento:
    myDiv.addEventListener('myClick', function () {
      console.log('Evento customizado disparado!');
    });
    
    myDiv.addEventListener('click', function () {
      // Disparar o evento:
      myDiv.dispatchEvent(myClickEvent);
    });
    <div id="my-div">Minha div (clique)</div>

    To learn more, I suggest reading:

    29.09.2018 / 18:22
    4

    If the idea is to trigger the myClick event whenever there is a click , you can do the following:

    const myClick = new Event('myClick');
    
    document.addEventListener('click', event => {
        EventTarget.prototype.dispatchEvent.call(event.target, myClick);
    });
    

    So, whenever the click event occurs, the myClick event for the same element will be triggered.

    const myClick = new Event('myClick');
    
    document.addEventListener('click', event => {
        EventTarget.prototype.dispatchEvent.call(event.target, myClick);
    });
    
    const lis = document.querySelectorAll('li');
    
    for (let li of lis) {
      li.addEventListener('myClick', event => console.log(event.target));
    }
    <ul>
      <li>Item 1</li>
      <li>Item 2</li>
      <li>Item 3</li>
      <li>Item 4</li>
      <li>Item 5</li>
    </ul>

    Note that even though all <li> elements have the myClick event, only the pressed element is triggered.

    However, since the event handled is click in document , it will only work if the element belongs to the node tree in document and the treated event propagates through it. If the element does not belong to the tree or the event is not propagating, the solution will not work. For example, see below an example of an element that is dynamically created and is not inserted into the tree in document . The event click of virtual will not propagate to document and therefore will not trigger myClick .

    const myClick = new Event('myClick');
    
    document.addEventListener('click', event => {
        EventTarget.prototype.dispatchEvent.call(event.target, myClick);
    });
    
    const virtual = document.createElement('span');
    
    virtual.addEventListener('myClick', event => console.log(event.target));
    virtual.click();

    However, if you add the element to the tree, document.body.appendChild(virtual) , the click event will trigger myClick normally. For non-propagating events, it will not work even if the element belongs to the node tree.

        
    11.10.2018 / 18:45
    0
    var evt = document.createEvent("Event");
    evt.initEvent("myEvent",true,true);
    
    // parametro customizado
    evt.foo = "bar";
    
    //registrar
    document.addEventListener("myEvent",myEventHandler,false);
    
    //invocar
    document.dispatchEvent(evt);
    

    This is just a simple example, more details on: link

        
    10.10.2018 / 23:07
    0

    I was able to do something similar, maybe not the best way, but it works:

    //Cria um evento de clique personalizado
    const myClick = new Event('myClick');
    
    //Salva a função em um lugar qualquer, no caso, escolhi o protótipo de EventTarget
    EventTarget.prototype._addEventListener = EventTarget.prototype.addEventListener;
    
    //Adiciona uma propriedade ao protótipo de EventTarget (poderia ser em qualquer outro lugar)
    EventTarget.prototype.customListener = {
      myClick: []
    };
    
    //Altera a função addEventListener
    EventTarget.prototype.addEventListener = function(type, listener, options) {
      //Se não houver a variável, a cria
      if (!EventTarget.prototype.customListener[type]) {
        EventTarget.prototype.customListener[type] = [];
      }
    
      //Adiciona o listener à lista
      EventTarget.prototype.customListener[type].push({
        element: this,
        callback: listener
      });
    
      //Chama a função antiga
      this._addEventListener(type, listener, options);
    }
    
    //Adiciona um ouvinte do evento personalizado aos elmentos
    document.querySelector('button').addEventListener('myClick', event => console.log('Clicked on button'));
    document.querySelector('a').addEventListener('myClick', event => console.log('Clicked on link'));
    
    //A lista de eventos:
    console.log(EventTarget.prototype.customListener)
    
    //Quando houver um clique na tela
    window.addEventListener('click', function(event) {
        //Percorre uma lista onde ficaria armazenado os elementos que foram adicionado ouvintes do evento
        for(listener of EventTarget.prototype.customListener.myClick) {
            //Se o elemento for igual ao elemento principal do clique na janela
            if (event.target === listener.element) {
                //Dispara o evento customizado de clique
                listener.callback(event);
            }
        }
    });
    <button>Click here!</button>
    
    <a href="#!">Click here too!</a>

    I'll implement a project and then post a more useful example (maybe cross-browser too)

        
    11.10.2018 / 18:13