webentwicklung-frage-antwort-db.com.de

Wie kann ich überprüfen, ob ein dynamisch verknüpfter Ereignis-Listener existiert oder nicht?

Hier ist mein Problem: Ist es irgendwie möglich, das Vorhandensein eines dynamisch angeschlossenen Ereignis-Listeners zu überprüfen? Oder wie kann ich den Status der Eigenschaft "onclick" (?) In DOM überprüfen? Ich habe Internet wie StackOverflow nach einer Lösung gesucht, aber kein Glück. Hier ist mein HTML:

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

Dann füge ich in Javascript einen dynamisch erstellten Ereignis-Listener an den 2. Link an:

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

Der Code läuft gut, aber alle meine Versuche, den angeschlossenen Listener zu erkennen, schlagen fehl:

// 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 ist hier ..__ Wenn Sie auf "Addclick for 2" und dann auf "[link 2]" klicken, wird das Ereignis gut ausgelöst. "Test link 2" meldet jedoch immer false . Kann jemand helfen?

50
Stano

Es gibt keine Möglichkeit zu überprüfen, ob dynamisch angeschlossene Ereignis-Listener vorhanden sind oder nicht. 

Der einzige Weg, um zu sehen, ob ein Ereignis-Listener angeschlossen ist, besteht darin, Ereignis-Listener wie folgt anzuhängen:

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

Sie können dann testen, ob ein Ereignislistener an onclick angehängt wurde, indem Sie !!elem.onclick (oder etwas Ähnliches) zurückgeben.

27
Ivan

Was ich tun würde, ist ein Boolean außerhalb Ihrer Funktion zu erstellen, der mit FALSE beginnt und beim Anhängen des Ereignisses auf TRUE gesetzt wird. Dies würde als eine Art Flag für Sie dienen, bevor Sie das Ereignis erneut anfügen. Hier ist ein Beispiel für die Idee.

// 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

Ich habe so etwas gemacht:

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');
    });
}

Ein spezielles Attribut für ein Element erstellen, wenn der Listener angehängt ist, und dann prüfen, ob es vorhanden ist. 

9
Karol Grabowski

Sie können jederzeit manuell überprüfen, ob Ihr EventListener mit Chrome Inspector vorhanden ist. In der Registerkarte "Element" befindet sich die herkömmliche Unterregisterkarte "Styles". In der Nähe befindet sich eine weitere: "Event Listeners" . Dadurch erhalten Sie die Liste aller EventListener mit ihren verknüpften Elementen.

5
Paul Leclerc

tl; dr : Nein, Sie können dies nicht auf nativ unterstützte Weise tun.


Die einzige Möglichkeit, dies zu erreichen, wäre das Erstellen eines benutzerdefinierten Speicherobjekts, in dem Sie die hinzugefügten Listener aufzeichnen. Etwas in den folgenden Zeilen:

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

Schritt 1: Zuerst benötigen Sie eine Funktion, die das Speicherobjekt durchlaufen und den Datensatz eines Elements zurückgeben kann, das das Element (oder false) enthält.

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

Schritt 2: Dann benötigen Sie eine Funktion, die einen Ereignis-Listener hinzufügen und den Listener auch in das Speicherobjekt einfügen kann.

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

Schritt 3: In Bezug auf die tatsächliche Anforderung Ihrer Frage benötigen Sie die folgende Funktion, um zu prüfen, ob einem Element ein Ereignislistener für ein bestimmtes Ereignis hinzugefügt wurde.

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

Schritt 4: Schließlich benötigen Sie eine Funktion, die einen Listener aus dem Speicherobjekt löschen kann.

/* 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>


Obwohl mehr als 5 Jahre vergangen sind, seit das OP die Frage veröffentlicht hat, werden meiner Meinung nach Menschen, die in der Zukunft auf diese Frage stoßen, von dieser Antwort profitieren. Sie können also Vorschläge oder Verbesserungen machen. ????

4
Angel Politis

Hier ist ein Skript, mit dem ich nach dem Vorhandensein eines dynamisch verbundenen Ereignis-Listeners gesucht habe. Ich habe mit jQuery einen Event-Handler an ein Element angehängt und dann dieses Event ausgelöst (in diesem Fall das 'click'-Event). Auf diese Weise kann ich Ereigniseigenschaften abrufen und erfassen, die nur vorhanden sind, wenn der Ereignishandler angehängt ist.

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

Mögliches Duplikat: Prüfen Sie, ob ein Element einen Ereignis-Listener enthält. keine jquery . Bitte finden Sie meine Antwort dort.

Im Grunde ist hier der Trick für Chrom (Chrome) Browser: 

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

Ich habe gerade ein Skript geschrieben, mit dem Sie dies erreichen können. Sie haben zwei globale Funktionen: hasEvent(Node Elm, String event) und getEvents(Node Elm), die Sie verwenden können. Beachten Sie, dass die EventTarget-Prototypmethode add/RemoveEventListener geändert wird und nicht für Ereignisse funktioniert, die durch HTML-Markup oder Javascript-Syntax von Elm.on_event = ... hinzugefügt werden.

Mehr Infos bei GitHub

Live Demo

Skript:

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

Wenn ich es richtig verstehe, können Sie nur überprüfen, ob ein Hörer überprüft wurde, nicht jedoch, welcher Hörer spezifisch präsentiert.

So würde ein Ad-hoc-Code die Lücke füllen, um Ihren Codierungsfluss zu handhaben. Eine praktische Methode wäre, ein state unter Verwendung von Variablen zu erstellen. Fügen Sie beispielsweise den Checker eines Listeners wie folgt hinzu:

var listenerPresent=false

wenn Sie dann einen Listener setzen, ändern Sie einfach den Wert:

listenerPresent=true

anschließend können Sie in Ihrem eventListener-Rückruf bestimmte Funktionen zuweisen und auf dieselbe Weise den Zugriff auf Funktionen in Abhängigkeit von einem bestimmten Status als Variable verteilen. Beispiel:

accessFirstFunctionality=false
accessSecondFunctionality=true
accessThirdFunctionality=true
0
Webwoman

Es scheint keine Cross-Browser-Funktion zu geben, die nach Ereignissen sucht, die unter einem bestimmten Element registriert sind.

Es ist jedoch möglich, die Rückruffunktionen für Elemente in einigen Browsern mithilfe ihrer Entwicklungstools anzuzeigen. Dies kann hilfreich sein, wenn Sie ermitteln möchten, wie eine Webseite funktioniert, oder wenn Sie Code debuggen.

Feuerfuchs

Sehen Sie sich zuerst das Element auf der Registerkarte Inspector in den Entwicklerwerkzeugen an. Das kann gemacht werden:

  • Auf der Seite klicken Sie mit der rechten Maustaste auf das Element auf der Webseite, das Sie untersuchen möchten, und wählen Sie "Inspect Element" aus dem Menü.
  • In der Konsole können Sie das Element mithilfe einer Funktion auswählen, z. B. document.querySelector, und dann auf das Symbol neben dem Element klicken, um es auf der Registerkarte Inspector anzuzeigen.

Wenn Ereignisse für das Element registriert wurden, wird eine Schaltfläche mit dem Wort Event neben dem Element angezeigt. Wenn Sie darauf klicken, können Sie die Ereignisse sehen, die mit dem Element registriert wurden. Durch Klicken auf den Pfeil neben einem Ereignis können Sie die Rückruffunktion dafür anzeigen.

Chrom

Sehen Sie sich zuerst das Element auf der Registerkarte Elements der Entwicklerwerkzeuge an. Das kann gemacht werden:

  • Auf der Seite klicken Sie mit der rechten Maustaste auf das Element auf der Webseite, das Sie untersuchen möchten, und wählen Sie "Inspect" aus dem Menü
  • Innerhalb der Konsole mit einer Funktion zur Auswahl des Elements, z. B. document.querySelector, mit der rechten Maustaste auf das Element klicken und "In Elementbedienfeld anzeigen" auswählen, um es im Inspector anzuzeigen. Tab.

In der Nähe des Abschnitts des Fensters, in dem der Baum mit den Webseitenelementen angezeigt wird, sollte sich ein weiterer Abschnitt mit einer Registerkarte mit dem Titel "Event Listeners" befinden. Wählen Sie es aus, um Ereignisse anzuzeigen, die für das Element registriert wurden. Um den Code für ein bestimmtes Ereignis anzuzeigen, klicken Sie auf den Link rechts davon.

In Chrome können Ereignisse für ein Element auch mit der Funktion getEventListeners gefunden werden. Basierend auf meinen Tests listet die Funktion getEventListeners jedoch keine Ereignisse auf, wenn mehrere Elemente an sie übergeben werden. Wenn Sie alle Elemente auf der Seite finden möchten, die über Listener verfügen und die Rückruffunktionen für diese Listener anzeigen, können Sie dazu den folgenden Code in der Konsole verwenden:

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

Bitte bearbeiten Sie diese Antwort, wenn Sie wissen, wie Sie dies in den angegebenen Browsern oder in anderen Browsern tun können.

0
Dave F