223 votes

Comment vérifier si l'auditeur d'événements attaché dynamiquement existe ou non ?

Voici mon problème : est-il possible de vérifier l'existence d'un récepteur d'événement attaché dynamiquement ? Ou comment puis-je vérifier l'état de la propriété "onclick" ( ?) dans le DOM ? J'ai cherché une solution sur Internet, comme sur Stack Overflow, mais sans succès. Voici mon code 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 récepteur d'événements créé dynamiquement au deuxième lien :

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

Le code s'exécute correctement, mais toutes mes tentatives de détection de l'auditeur 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 est ici . Si vous cliquez sur "Add onclick for 2" puis sur "[link 2]", l'événement se déclenche bien, mais l'événement "Test link 2" est toujours faux. Quelqu'un peut-il m'aider ?

3voto

denkdirnix Points 21

// Il suffit de prendre ceci et d'attribuer l'attribut à l'extérieur de la fonction anonyme

const element = document.getElementById('div');
if (element && !element.hasAttribute('listenerOnClick')) {
    element.addEventListener('click', function () {
        const elementClicked = this;
        // fnDoAnything(this); // maybe call a function with the elementClicked...
        console.log('event has been attached');
    });
}
element.setAttribute('listenerOnClick', 'true');

2voto

Greg2fs Points 172

Il suffit de supprimer l'événement avant de l'ajouter :

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

1voto

carinlynchin Points 306

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

si vous le faites :

item.onclick

il renverra "null"

mais si c'est le cas :

item.hasOwnProperty('onclick')

alors c'est "VRAI"

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

1voto

Webman Points 404

Si j'ai bien compris, vous pouvez seulement vérifier si un auditeur a été contrôlé, mais pas quel auditeur est le présentateur en particulier.

Ainsi, un code ad hoc comblerait l'écart pour gérer votre flux de codage. Une méthode pratique consisterait à créer un state en utilisant des variables. Par exemple, attachez un vérificateur d'auditeur comme suit :

var listenerPresent=false

alors si vous mettez en place un listener, il suffit de changer la valeur :

listenerPresent=true

alors dans le callback de votre eventListener vous pouvez assigner des fonctionnalités spécifiques à l'intérieur et de la même manière, distribuer l'accès aux fonctionnalités en fonction d'un certain état comme une variable par exemple :

accessFirstFunctionality=false
accessSecondFunctionality=true
accessThirdFunctionality=true

1voto

Mike Gashler Points 398

J'ai écrit une extension Chrome qui devait déterminer quels éléments de la page réagissaient aux clics. Voici comment j'ai procédé :

(1) Dans manifest.json, définissez l'attribut "run_at" à "document_start". (Nous devons injecter un script avant que la page ne commence à s'exécuter).

(2) Dans votre contenu script, ajoutez un peu de code pour injecter un script dans la page qui surchargera EventTarget.prototype.addEventListener pour marquer tous les éléments qui sont dynamiquement assignés à des écouteurs de clics :

let flagClickHandledElements = function() {
    let oldEventListener = EventTarget.prototype.addEventListener;
    EventTarget.prototype.addEventListener = function(event_name, handler_func) {
        if (event_name === 'click') {
            if (this.setAttribute) {
                this.setAttribute('data-has_click_handler', true);
            }
        }
        if (oldEventListener)
            oldEventListener(event_name, handler_func);
    }
}

function injectScript(func) {
    let codeString = '(' + func + ')();';
    let script = document.createElement('script');
    script.textContent = codeString;
    (document.head||document.documentElement).appendChild(script);
}

injectScript(flagClickHandledElements);

(3) Ajoutez "webNavigation" à votre liste de "permissions" dans manifest.json

(4) Ajoutez du code à votre arrière-plan script pour avertir le contenu script lorsque le chargement de la page est terminé :

function onPageDoneLoading(details)
{
    chrome.tabs.sendMessage(details.tabId, {"action": "doneloading"});
}

chrome.webNavigation.onCompleted.addListener(onPageDoneLoading);

(5) Lorsque la page finit de se charger, faites en sorte que votre contenu script injecte un autre script dans la page qui analyse tous les éléments de la page à la recherche de gestionnaires "onclick" à l'ancienne :

let gatherOldStyleClickHandledElements = function() {
    let all_elements = document.getElementsByTagName("*");
    for (let i = 0; i < all_elements.length; i++) {
        let el = all_elements[i];
        if (el.setAttribute && el.onclick) {
            el.setAttribute('data-has_click_handler', true);
        }
    }
}

function onReceiveMessage(request) {
    if (request.action === 'doneloading') {
        injectScript(gatherOldStyleClickHandledElements);
    } else {
        console.log('Unrecognized message');
    }

    return Promise.resolve("Dummy response to keep the console quiet");
}

(6) Enfin, vous pouvez tester un élément de votre contenu script pour voir s'il possède un gestionnaire de clic comme ceci :

if (el.getAttribute('data-has_click_handler'))
    console.log('yep, this element has a click handler');

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X