web-dev-qa-db-fra.com

Comment vérifier si un écouteur d'événements attaché dynamiquement existe ou non?

Voici mon problème: est-il possible en quelque sorte de vérifier l'existence d'écouteurs d'événements attachés dynamiquement? Ou comment puis-je vérifier le statut de la propriété "onclick" (?) Dans DOM? J'ai cherché sur internet exactement comme StackOverflow, 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 le 2e lien au programme d'écoute d'événement créé de manière dynamique:

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

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

// 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 is here . Si vous cliquez sur "Ajouter un clic pour 2" puis sur "[lien 2]", l'événement se déclenche correctement, mais le "lien de test 2" indique toujours faux . Quelqu'un peut aider?

50
Stano

Il n'y a aucun moyen de vérifier s'il existe ou non des écouteurs d'événements liés de manière dynamique. 

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

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

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

27
Ivan

Ce que je voudrais faire est de créer un booléen en dehors de votre fonction qui commence par FALSE et qui est défini sur TRUE lorsque vous attachez l'événement. Cela servirait comme une sorte de drapeau pour vous avant de joindre l'événement à nouveau. 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);
    }
}
17
Cesar

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éation d'un attribut spécial pour un élément lorsque l'auditeur est attaché, puis vérification de son existence. 

9
Karol Grabowski

Vous pouvez toujours vérifier manuellement si votre EventListener existe en utilisant l'inspecteur de Chrome, par exemple . Dans l'onglet Elément, vous avez le sous-onglet "Styles" traditionnel et près d'un autre: "Auditeurs d'événement" . de tous les EventListeners avec leurs éléments liés.

5
Paul Leclerc

tl; dr : Non, vous ne pouvez pas le faire de manière native.


Le seul moyen que je connaisse pour y parvenir serait de créer un objet de stockage personnalisé dans lequel vous gardez une trace des écouteurs ajoutés. Quelque chose dans les lignes suivantes:

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

Étape 1: Vous aurez d’abord besoin d’une fonction capable de parcourir l’objet de stockage et de renvoyer l’enregistrement d’un élément donné (ou faux).

/* 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’une fonction permettant d’ajouter un écouteur d’événement, mais aussi d’insérer celui-ci dans 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 permettant de supprimer un écouteur de l’objet stockage.

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

Snippet:

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 cinq ans se soient écoulés depuis que le PO ait posté la question, je pense que les personnes qui tomberont sur elle à l'avenir bénéficieront de cette réponse. N'hésitez donc pas à faire des suggestions ou à l'améliorer. ????

4
Angel Politis

Voici un script que j'ai utilisé pour vérifier l'existence d'un écouteur d'événements 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 des propriétés d'événement 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
dsmith63

Doublage possible: Vérifie si un élément a un écouteur d'événements. non jquery . .__ Veuillez trouver ma réponse ici.

En gros, voici le truc pour le navigateur Chrome (Chrome): 

getEventListeners(document.querySelector('your-element-selector'));
3
arufian

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 que cela modifie la méthode prototype EventTargetadd/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émo 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
Gaurang Tandon

Si je comprends bien, vous pouvez uniquement vérifier si un auditeur a été vérifié, mais pas quel auditeur est présentateur en particulier.

Donc, un code ad hoc permettrait de combler le vide pour gérer votre flux de codage. Une méthode pratique consisterait à créer une state à l'aide de variables. Par exemple, attachez le vérificateur d'un auditeur comme suit:

var listenerPresent=false

alors si vous définissez un auditeur, changez simplement la valeur:

listenerPresent=true

ensuite, dans le callback de votre eventListener, vous pouvez affecter des fonctionnalités spécifiques à l'intérieur et, de la même manière, répartir l'accès aux fonctionnalités en fonction d'un état donné, par exemple:

accessFirstFunctionality=false
accessSecondFunctionality=true
accessThirdFunctionality=true
0
Webwoman

Il ne semble pas exister de fonction de navigateur mixte permettant de rechercher des événements enregistrés sous un élément donné.

Cependant, il est possible d'afficher les fonctions de rappel pour les éléments de 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 pour le code de débogage.

Firefox

Commencez par afficher l'élément dans l'onglet Inspecteur des outils de développement. Ceci peut être fait:

  • Sur la page en cliquant avec le bouton droit de la souris sur l'élément de la page Web que vous souhaitez 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, tel que document.querySelector, puis en cliquant sur l'icône située en regard de l'élément pour l'afficher dans le Inspecteur languette.

Si des événements ont été enregistrés dans l'élément, un bouton contenant le mot événement apparaît à côté de l'élément. En cliquant dessus, vous pourrez voir les événements qui ont été enregistrés avec l'élément. En cliquant sur la flèche en regard d'un événement, vous pouvez afficher la fonction de rappel correspondante.

Chrome

Commencez par afficher l'élément dans l'onglet Eléments dans les outils de développement. Ceci peut être fait:

  • Sur la page en cliquant avec le bouton droit de la souris sur l'élément de la page Web que vous souhaitez inspecter et en sélectionnant "Inspecter" dans le menu.
  • Dans la console en utilisant une fonction pour sélectionner l'élément, tel que document.querySelector, en cliquant avec le bouton droit de la souris sur l'élément et en sélectionnant "Révéler dans le panneau Eléments" pour l'afficher dans la Inspecteur onglet.

Près de la section de la fenêtre qui affiche 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-le pour voir les événements qui ont été enregistrés pour l'élément. Pour voir le code d'un événement donné, cliquez sur le lien à sa droite.

Dans Chrome, les événements d'un élément peuvent également être trouvés à l'aide de 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 souhaitez rechercher tous les éléments de la page dotés d'écouteurs et afficher les fonctions de rappel pour ces écouteurs, vous pouvez utiliser le code suivant dans la console pour cela:

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 éditer cette réponse si vous connaissez des moyens de le faire dans les navigateurs donnés ou dans d’autres navigateurs.

0
Dave F