Comment vérifier si l'écouteur d'événement attaché dynamiquement existe ou non?

Voici mon problème: est-il possible de vérifier l'existence d'un écouteur d'événement attaché dynamiquement? Ou comment puis-je vérifier l'état du "onclick" (?) de la propriété dans les DOM? J'ai cherché internet tout comme StackOverflow pour une solution, mais pas de chance. Voici mon html:

<a id="link1" onclick="linkclick(event)"> link 1 </a>
<a id="link2"> link 2 </a> <!-- without inline onclick handler -->

Ensuite, en javascript, j'attache un écouteur d'événement créé dynamiquement au 2ème lien:

document.getElementById('link2').addEventListener('click', linkclick, false);

Le code fonctionne bien, mais toutes mes tentatives pour détecter cet écouteur attaché échec:

// test for #link2 - dynamically created eventlistener
alert(elem.onclick); // null
alert(elem.hasAttribute('onclick')); // false
alert(elem.click); // function click(){[native code]} // btw, what's this?

JsFiddle est ici. Si vous cliquez sur "Ajouter onclick pour 2 "puis" [lien 2]", l'événement se déclenche bien, mais le "Test link 2" signale toujours faux. Quelqu'un peut-il aider?

44
demandé sur Csaba 2012-07-12 19:42:01

11 réponses

Il N'y a aucun moyen de vérifier si les écouteurs d'événements attachés dynamiquement existent ou non.

La seule façon de voir si un écouteur d'événement est attaché est d'attacher des écouteurs d'événements comme ceci:

elem.onclick = function () { console.log (1) }

, Vous pouvez tester si un écouteur d'événement a été attaché à onclick, en retournant !!elem.onclick (ou quelque chose de similaire).

22
répondu Ivan 2012-07-12 15:58:14

Ce que je ferais est de créer un booléen en dehors de votre fonction qui commence comme FALSE et est défini sur TRUE lorsque vous attachez l'événement. Cela servirait comme une sorte de drapeau pour vous avant de joindre à nouveau l'événement. Voici un exemple de l'idée.

// initial load
var attached = false;

// this will only execute code once
doSomething = function() {
  if (!attached) {
    attached = true;
    //code
  }
} 

//attach your function with change event
window.onload = function() {
    var txtbox = document.getElementById("textboxID");
    if(window.addEventListener){
        txtbox.addEventListener("change", doSomething, false);
    } else if(window.attachEvent){
        txtbox.attachEvent("onchange", doSomething);
    }
}
16
répondu Cesar 2017-10-11 19:45:37

J'ai fait quelque chose comme ça:

const element = document.getElementById('div');

if (element.getAttribute('listener') !== 'true') {
     element.addEventListener('click', function (e) {
         const elementClicked = e.target;
         elementClicked.setAttribute('listener', 'true');
         console.log('event has been attached');
    });
}

Créer un attribut spécial pour un élément lorsque l'écouteur est attaché, puis vérifier s'il existe.

6
répondu Karol Grabowski 2017-11-16 12:56:24

Vous pouvez toujours vérifier manuellement si votre EventListener existe en utilisant Chrome inspector par exemple. Dans l'onglet élément, vous avez le sous-onglet "Styles" traditionnel et près d'un autre: "écouteurs D'événements". Ce qui vous donnera la liste de tous les EventListeners avec leurs éléments liés.

4
répondu Paul Leclerc 2016-05-12 15:12:25

Tl; dr : Non, vous ne pouvez pas le faire de manière nativement supportée.


La seule façon que je connaisse pour y parvenir serait de créer un objet de stockage personnalisé où vous conservez un enregistrement des écouteurs ajoutés. Quelque chose dans les lignes suivantes:

/* Create a storage object. */
var CustomEventStorage = [];

Étape 1: tout d'abord, vous aurez besoin d'une fonction qui peut traverser l'objet de stockage et retourner l'enregistrement d'un élément donné à l'élément (ou false).

/* The function that finds a record in the storage by a given element. */
function findRecordByElement (element) {
    /* Iterate over every entry in the storage object. */
    for (var index = 0, length = CustomEventStorage.length; index < length; index++) {
        /* Cache the record. */
        var record = CustomEventStorage[index];

        /* Check whether the given element exists. */
        if (element == record.element) {
            /* Return the record. */
            return record;
        }
    }

    /* Return false by default. */
    return false;
}

Étape 2: Ensuite, vous aurez besoin d'un fonction qui peut ajouter un écouteur d'événement, mais aussi insérer l'écouteur à l'objet de stockage.

/* The function that adds an event listener, while storing it in the storage object. */
function insertListener (element, event, listener, options) {
    /* Use the element given to retrieve the record. */
    var record = findRecordByElement(element);

    /* Check whether any record was found. */
    if (record) {
        /* Normalise the event of the listeners object, in case it doesn't exist. */
        record.listeners[event] = record.listeners[event] || [];
    }
    else {
        /* Create an object to insert into the storage object. */
        record = {
            element: element,
            listeners: {}
        };

        /* Create an array for event in the record. */
        record.listeners[event] = [];

        /* Insert the record in the storage. */
        CustomEventStorage.push(record);
    }

    /* Insert the listener to the event array. */
    record.listeners[event].push(listener);

    /* Add the event listener to the element. */
    element.addEventListener(event, listener, options);
}

Étape 3: en ce qui concerne l'exigence réelle de votre question, vous aurez besoin de la fonction suivante pour vérifier si un élément a été ajouté un écouteur d'événement pour un événement spécifié.

/* The function that checks whether an event listener is set for a given event. */
function listenerExists (element, event, listener) {
    /* Use the element given to retrieve the record. */
    var record = findRecordByElement(element);

    /* Check whether a record was found & if an event array exists for the given event. */
    if (record && event in record.listeners) {
        /* Return whether the given listener exists. */
        return !!~record.listeners[event].indexOf(listener);
    }

    /* Return false by default. */
    return false;
}

Étape 4: enfin, vous aurez besoin d'une fonction qui peut supprimer un écouteur du stockage objet.

/* The function that removes a listener from a given element & its storage record. */
function removeListener (element, event, listener, options) {
    /* Use the element given to retrieve the record. */
    var record = findRecordByElement(element);

    /* Check whether any record was found and, if found, whether the event exists. */
    if (record && event in record.listeners) {
        /* Cache the index of the listener inside the event array. */
        var index = record.listeners[event].indexOf(listener);

        /* Check whether listener is not -1. */
        if (~index) {
            /* Delete the listener from the event array. */
            record.listeners[event].splice(index, 1);
        }

        /* Check whether the event array is empty or not. */
        if (!record.listeners[event].length) {
            /* Delete the event array. */
            delete record.listeners[event];
        }
    }

    /* Add the event listener to the element. */
    element.removeEventListener(event, listener, options);
}

Extrait de Code:

window.onload = function () {
  var
    /* Cache the test element. */
    element = document.getElementById("test"),

    /* Create an event listener. */
    listener = function (e) {
      console.log(e.type + "triggered!");
    };

  /* Insert the listener to the element. */
  insertListener(element, "mouseover", listener);

  /* Log whether the listener exists. */
  console.log(listenerExists(element, "mouseover", listener));

  /* Remove the listener from the element. */
  removeListener(element, "mouseover", listener);

  /* Log whether the listener exists. */
  console.log(listenerExists(element, "mouseover", listener));
};
<!-- Include the Custom Event Storage file -->
<script src = "https://cdn.rawgit.com/angelpolitis/custom-event-storage/master/main.js"></script>

<!-- A Test HTML element -->
<div id = "test" style = "background:#000; height:50px; width: 50px"></div>

bien que plus de 5 années se soient écoulées depuis que le PO a posté la question, je crois que les gens qui trébuchent sur elle à l'avenir bénéficieront de cette réponse, alors n'hésitez pas à faire des suggestions ou des améliorations à elle.

4
répondu Angel Politis 2017-11-21 13:42:48

Voici un script que j'ai utilisé pour vérifier l'existence d'un écouteur d'événement attaché dynamiquement. J'ai utilisé jQuery pour attacher un gestionnaire d'événements à un élément, puis déclencher cet événement (dans ce cas, l'événement 'click'). De cette façon, je peux récupérer et capturer les propriétés d'événements qui n'existeront que si le gestionnaire d'événements est attaché.

var eventHandlerType;

$('#contentDiv').on('click', clickEventHandler).triggerHandler('click');

function clickEventHandler(e) {
    eventHandlerType = e.type;
}

if (eventHandlerType === 'click') {
    console.log('EventHandler "click" has been applied');
}
3
répondu dsmith63 2014-05-16 16:10:03

Doublon Possible: Vérifiez si un élément contient un écouteur d'événement. pas de jquery. Veuillez trouver ma réponse.

Fondamentalement, voici l'astuce pour Chrome (Chrome) Navigateur:

getEventListeners(document.querySelector('your-element-selector'));
2
répondu arufian 2018-07-04 06:52:26

Je viens d'écrire un script qui vous permet d'y parvenir. Il vous donne deux fonctions globales: hasEvent(Node elm, String event) et getEvents(Node elm) que vous pouvez utiliser. Sachez qu'il modifie la méthode EventTarget prototype add/RemoveEventListener, et ne fonctionne pas pour les événements ajoutés via le balisage HTML ou la syntaxe javascript de elm.on_event = ...

Plus d'infos sur GitHub

Démonstration En Direct

Script:

var hasEvent,getEvents;!function(){function b(a,b,c){c?a.dataset.events+=","+b:a.dataset.events=a.dataset.events.replace(new RegExp(b),"")}function c(a,c){var d=EventTarget.prototype[a+"EventListener"];return function(a,e,f,g,h){this.dataset.events||(this.dataset.events="");var i=hasEvent(this,a);return c&&i||!c&&!i?(h&&h(),!1):(d.call(this,a,e,f),b(this,a,c),g&&g(),!0)}}hasEvent=function(a,b){var c=a.dataset.events;return c?new RegExp(b).test(c):!1},getEvents=function(a){return a.dataset.events.replace(/(^,+)|(,+$)/g,"").split(",").filter(function(a){return""!==a})},EventTarget.prototype.addEventListener=c("add",!0),EventTarget.prototype.removeEventListener=c("remove",!1)}();
0
répondu Gaurang Tandon 2015-06-10 10:40:16

Il ne semble pas y avoir de fonction Cross browser qui recherche les événements enregistrés sous un élément donné.

Cependant, il est possible d'afficher les fonctions de rappel des éléments dans certains navigateurs à l'aide de leurs outils de développement. Cela peut être utile lorsque vous tentez de déterminer le fonctionnement d'une page web ou de déboguer du code.

Firefox

Tout d'Abord, afficher l'élément dans le Inspecteur onglet dans les outils de développement. Cela peut être fait:

  • Sur la page par un clic droit sur l'élément de la page web que vous voulez inspecter et en sélectionnant "Inspecter l'Élément" dans le menu.
  • dans la console en utilisant une fonction pour sélectionner l'élément, comme document.querySelector, puis en cliquant sur l'icône à côté de l'élément à afficher dans la Inspecteur onglet.

Si des événements ont été enregistrés dans l'élément, vous verrez un bouton contenant le mot Événement à côté de l'élément. Cliquer dessus vous permettra de voir les événements qui ont été enregistrés avec l'élément. Cliquer sur la flèche à côté d'un événement vous permet d'afficher la fonction de rappel pour celui-ci.

Chrome

Tout d'abord, affichez l'élément dans l'onglet Elements dans les outils de développement. Cela peut être fait:

  • sur la page en cliquant avec le bouton droit sur l'élément de la page web que vous souhaitez inspecter et en sélectionnant "inspecter" à partir de le menu
  • dans la console en utilisant une fonction pour sélectionner l'élément, comme document.querySelector , Cliquez avec le bouton droit sur l'élément et sélectionnez "révéler dans le panneau éléments" pour l'afficher dans l'onglet Inspecteur.

Près de la section de la fenêtre qui montre l'arborescence contenant les éléments de la page web, il devrait y avoir une autre section avec un onglet intitulé "event Listeners". Sélectionnez pour voir les événements qui ont été enregistrés à l'élément. De voir le code pour un événement donné, cliquez sur le lien à droite de celui-ci.

Dans Chrome, les événements d'un élément peuvent également être trouvés en utilisant la fonction getEventListeners. Cependant, sur la base de mes tests, la fonction geteventlisteners ne répertorie pas les événements lorsque plusieurs éléments lui sont transmis. Si vous voulez trouver tous les éléments de la page qui ont des écouteurs et afficher les fonctions de rappel pour ces écouteurs, vous pouvez utiliser le code suivant dans la console pour faire ce:

var elems = document.querySelectorAll('*');

for (var i=0; i <= elems.length; i++) {
    var listeners = getEventListeners(elems[i]);

    if (Object.keys(listeners).length < 1) {
        continue;
    }

    console.log(elems[i]);

    for (var j in listeners) {
        console.log('Event: '+j);

        for (var k=0; k < listeners[j].length; k++) {
            console.log(listeners[j][k].listener);
        }
    }
}

Veuillez modifier cette réponse si vous connaissez des moyens de le faire dans les navigateurs donnés ou dans d'autres navigateurs.

0
répondu Dave F 2018-09-29 18:04:07

Je viens de découvrir cela en essayant de voir si mon événement était attaché....

Si vous le faites:

item.onclick

Il renverra "null"

Mais si vous le faites:

item.hasOwnProperty('onclick')

Alors c'est "vrai"

Donc, je pense que lorsque vous utilisez "addEventListener" pour ajouter des gestionnaires d'événements, la seule façon d'y accéder est via "hasOwnProperty". J'aimerais savoir pourquoi ou comment, mais hélas, après des recherches, je n'ai pas trouvé d'explication.

-1
répondu carinlynchin 2015-04-29 16:13:31

Vous pouvez en théorie associer addEventListener et removeEventListener pour ajouter un drapeau à l'objet 'this'. Moche et je ne l'ai pas testé ...

-1
répondu kofifus 2018-05-10 03:06:44