Dynamisches <a> element erstellen mit # innerhalb der href Anweisung
bits
- html
- javascript
Hallo
Ich habe ein Problem bei der dynamischen Erstellung von accordions. Ich habe mir folgende Funktion erstellt, welche dem div "accordion-section" ein weiteres accordion element hinzufügen soll. Das funktioniert auch soweit. Jedoch will die verlinkung mit dem accordion content einfach nicht funktionieren. Statisch ist es kein Problem (Siehe code weiter unten). Durch lange tests vermute ich das die href anweisung ein problem macht. Das Problem tacht nur beim setzen des href attributs mittels javascript auf. Kann es sein das Javascript mit der Raute innerhalb der href Anweisung nicht zurecht kommt. Ich habe es auch schon mit %23 anstatt die # versucht. Dies führt jedoch auch nicht zum gewünschten ergebnis.
function dynamicAccordion(){
var a = document.createElement("a");
a.className = "accordion-section-title";
a.href = "#accordion-20";
a.innerHTML = "Inhalt 1";
document.getElementById("accordionSection").appendChild(a);
var div = document.createElement("div");
div.className = "accordion-section-content";
div.id = "accordion-20";
var p = document.createElement("p");
p.innerHTML = "Content";
div.appendChild(p);
document.getElementById("accordionSection").appendChild(div);
}
<a class="accordion-section-title" href="#accordion-20" Inhalt 1></a>
<div id="accordion-20" class="accordion-section-content">
<p>Content</p>
</div>
Der JavaScript code für die Accordions sieht wie folgt aus. Dieser funktioniert jedoch sehr gut solange ich alle Elemente statisch erzeuge.
$('.accordion-section-title').click(function(e) {
// Grab current anchor value
$('.accordion input[type="checkbox"]').click(function(e) {
e.stopPropagation();
});
var currentAttrValue = $(this).attr('href');
if ($(e.target).is('.active')) {
close_accordion_section();
} else {
close_accordion_section();
// Add active class to section title
$(this).addClass('active');
// Open up the hidden content panel
$('.accordion ' + currentAttrValue).slideDown(300).addClass('open');
}
e.preventDefault();
});
Hi, meinst du mit dynamisch, nachträglich generierte Elemente? Wenn ja, ist das mit JQuery nicht so einfach die anzusprechen. Google mal den Nachfolger von ‘live-Funktion’
Ja genau das meine ich. Ich will nach einer bestimmten aktion z.B. in button klick, ein neues accordion unterelement erzeugen. Kann JQuery keine ich sag mal "zur laufzeit" erstellten elemente ansprechen?
Hi ,
Ja genau das meine ich. Ich will nach einer bestimmten aktion z.B. in button klick, ein neues accordion unterelement erzeugen. Kann JQuery keine ich sag mal "zur laufzeit" erstellten elemente ansprechen?
Also mit der Nachfolgerfunktion kam ich nicht zurecht - komm mit JQ1.4 bei meinem Modul aus. zB.: Für meinen Warenkorb
$("#Tab_korb :input").live('change click', function (e) { // live bindet zugefügte elemente nur bis JQuery 1.4.1
...
});
Tach!
Kann JQuery keine ich sag mal "zur laufzeit" erstellten elemente ansprechen?
Doch, es kann, in einem gewissen Sinne. Es kann nur nicht zaubern, sondern muss sich an die zugrundeliegenden Möglichkeiten und Gegebenheiten halten. Es kann jedenfalls keine Eventhandler bis in alle Zukunft an neu erstellte Elemente binden. Direkt binden geht nur an vorhandene Elemente. Der stattdessen verwendbare Mechanismus nennt sich Event Bubbling. Ereignisse (mit Ausnahmen) blubbern die Vorfahrenkette nach oben. Du musst dich für dein Problem an einen die ganze Zeit existierenden Vorfahren hängen und dort auf das Ereignis warten. Wenn es auftritt, wird dein dort hängender Eventhandler mit einem Parameter aufgerufen. In dem findest du das eigentliche Ziel des Events, welches also der nachträglich eingefügte Button oder was auch immer ist. Wie das genau geht, ist garantiert schon irgendwo im Netz beschrieben. Suche nach: jQuery Event Bubbling.
dedlfix.
Hallo
Kann JQuery keine ich sag mal "zur laufzeit" erstellten elemente ansprechen?
Doch, es kann, in einem gewissen Sinne. Es kann nur nicht zaubern, sondern muss sich an die zugrundeliegenden Möglichkeiten und Gegebenheiten halten. […]
This.
Wann wurde hier eigenlich zuletzt darüber diskutiert, wie sinnvoll es ist jQuery zu verwenden, wenn man JavaScript nicht beherrscht? ;-)
Ich meine mich dunkel daran erinnern zu können, hierzu mal einen schönen Vergleich gelesen zu haben, frei nach Camping_RIDER:
„jQuery verwenden ohne JavaScript zu können ist wie einen Rennwagen zu fahren ohne einen Führerschein zu haben.“
Jedenfalls ist die Geschichte mit den Events eigentlich nicht wirklich schwer zu verstehen, wenn man sich die Mühe macht, sich wenigstens etwas in die Materie einzulesen…
Event Handling
Fangen wir mal damit an, was HTML-Elemente eigentlich sind, nämlich in erster Linie Objekte in der internen Repräsentation des Document Object Models, welche der Browser auf Grundlage des HTML-Dokumentes und der eingebundenen Skripte erstellt.
Diese Objekte, welche also die Elemente repräsentieren, verfügen nun über eine Schnittstelle Event Target, die es unter anderem erlaubt, Event Listener hinzuzufügen und wieder zu löschen:
element.addEventListener('event', callback, capture);
element.removeEventListener('event', callback, capture);
Das heißt, jedes Element hat eine assoziierte Liste der für dieses Element registrierten Event Listener.
Wobei zu beachten ist, dass keine identischen Event Listener für ein Element existieren dürfen, sprich, wenn man für das gleiche Element mehr als einen Event Listener mit den selben Argumenten registriert, dann wird der bestehende Listeneintrag durch die nachfolgenden überschrieben. Aber das nur nebenbei.
Jedenfalls dürfte dadurch klar werden, dass man keine Event Handler für DOM-Objekte registrieren kann, die zum Zeitpunkt dieser Operation noch gar nicht existieren…
Aber weiter im Text: Was sind eigentlich Events?
Events sind ebenfalls Objekte, also Container für Eigenschaften und Methoden, auf die über die Schnittstelle Event zugegriffen werden kann.
Dies ist möglich, da das Event einem assoziierten Event Handler als Parameter übergeben wird:
var callback = function (e) {
var event = e;
};
element.addEventListener('click', callback);
// oder
element.addEventListener('click', function (e) {
var event = e;
});
Zu den Eigenschaften gehört hier nun in erster Linie der Typ des Events, welcher den Event Listenern als steuernder Eingabeparameter übergeben wird, und der wiefolgt ausgelesen werden kann:
element.addEventListener('click', function (e) {
var eventType = e.type; // 'click'
});
Weiterhin gehört zu den Attributen eines Events das Zielobjekt, also das DOM-Objekt, an welches das Event verschickt wird:
document.addEventListener('click', function (e) {
var targetElement = e.target;
});
Darüber hinaus gibt es auch noch eine Eigenschaft, in welcher das DOM-Objekt, also in der Regel das Element hinterlegt ist, dessen Event Listener tatsächlich aufgerufen wurde, und welches sich von dem eigentlichen Zielobjekt, wie wir gleich noch sehen werden, unterscheiden kann:
element.addEventListener('click', function (e) {
var thisElement = e.currentTarget;
});
Hierbei sei noch angemerkt, dass der Wert von e.currentTarget
beim Aufruf der Callback-Funktion als deren this-Wert fungiert, das Element, für welches der Event Listener registriert wurde, also über this referenziert werden kann:
element.addEventListener('click', function (e) {
var thisElement = this; // this = e.currentTarget
});
Abgesehen von den bereits genannten Event-Attributen, gibt es natürlich noch einige Eigenschaften und Methoden mehr, deren Verständnis allerdings voraussetzt, dass man verstanden hat, wie die Event-Objekte überhaupt zu ihren Zielobjekten gelangen…
Es ist nämlich keinesfalls so, dass die Events nur an dasjenige DOM-Objekt übergeben werden, welches als event.target
hinterlegt ist, sondern im Gegenteil ist es so, dass die Events über das globale Objekt in die Struktur des DOM eingespeist werden, das heißt in dem Fall, dass es sich bei dem User Agent um einen Browser handelt, ist Window die erste Station des Events.
Wenn ein Event versandt wird, dann wird intern ein sogenannter Eventpfad festgelegt, der, ausgehend vom Zielelement, also dem Event Target, bis hoch zum globalen Window-Objekt alle Vorfahrenelemente von target
umfasst.
Beispiel:
<body>
<header>
<h1> Hallo Welt </h1>
</header>
</body>
… und …
var heading = document.getElementsByTagName('h1')[0];
heading.addEventListener('click', function (e) {
// ...
});
Hier ist nun ein Event Listener für das H1-Element registriert, und wenn jetzt auf dieses Element geklickt wird, dann sieht der Eventpfad des 'click'-Events zunächst so aus:
| window | document | body | header | h1 |
Das Event-Objekt wird also von jeder Station an die jeweils nächste entlang des Pfades weitergereicht.
Dabei ist im Übrigen zu beachten, dass der Event Path bereits zum Zeitpunkt des Versands (event dispatch) festgelegt wird, das heißt, Änderungen im DOM, die nach dem Feuern des Events vorgenommen werden, haben auf den Weg des Events keinen Einfluss.
Diese erste Phase, die jedes Event durchläuft, nennt man CAPTURING-PHASE, und sie dauert, so man sie nicht unterbricht, solange, bis das als Wert der Eigenschaft e.target
hinterlegte Zielelement erreicht ist.
Ist das Event also bei…
| h1 |
…angekommen, dann ist die Capturing-Phase abgeschlossen und das Event tritt in die sogenannte TARGET-PHASE ein.
Bei den meisten (aber nicht bei allen) Event-Typen passiert an dieser Stelle nun folgendes:
Die Liste der Vorfahrenelemente, also der Eventpfad wird umgedreht, so dass nunmehr das Zielelement an erster, und das globale Window-Objekt an letzter Stelle steht. Für unser Beispiel also:
| h1 | header | body | document | window |
Und jetzt beginnt das ganze Spiel von vorne, sprich, das Event durchläuft nun ausgehend vom Zielelement die ganze Kette der Vorfahrenelemente zurück bis hoch zu Window, und diese dritte Phase nennt man BUBBLING-PHASE.
Wenn man nun diese (in der Regel) drei Phasen zusammennimmt, sprich man auch vom Eventfluss (event-flow).
Die Phase, in welcher sich das Event gerade befindet, ist in der Event-Eigenschaft eventPhase
hinterlegt, kann also wiefolgt ausgelesen werden:
element.addEventListener('click', function (e) {
var phase = e.eventPhase // z.B. 1 / 'CAPTURING_PHASE'
}, true);
Mit diesem Hintergrund wissen können wir uns also der Frage zuwenden, was Event Delegation bedeutet.
Event Delegation
Event Delegation bedeutet, ein Event auf seinem Weg durch das DOM an einer anderen Stelle abzufangen, als an dessen Zielelement.
Denn während das Event die Vorfahrenelemente des Event Target passiert, werden alle für diese Elemente registrierten Event Listener ausgelöst, die für diesen Event-Typ bestimmt sind!
Um also in unserem Beispiel zu bleiben, könnten wir den Event Listener statt für H1 zum Beispiel auch für BODY registrieren:
document.body.addEventListener('click', function (e) {
if (e.target.tagName === 'h1') {
// do something
}
});
Das heißt es ist möglich, Ereignisse an einer anderen Stelle zu verarbeiten, als direkt am Zielelement.
Man kann also statt für jedes einzelne DOM-Objekt Event Listener zu registrieren, auch einen einzigen Eventlistener auf einer höheren Hierarchieebene registrieren, um die Selektion der Zielelemente dann mittels der in e.target
hinterlegten Werte innerhalb der Callback-Funktion vorzunehmen.
Dadurch lässt sich der Code zur Eventverarbeitung deutlich übersichtlicher strukturieren.
Man könnte sich das Ganze also in etwa vorstellen wie die Fahrt mit einem Bus im öffentlichen Nahverkehr:
Das heißt, zunächst steht der Bus im Depot (Window), wo der Busfahrer einen Plan für seine Route überreicht bekommt (Eventpath), in dem alle seine Stationen vom Depot bis hin zur Endhaltestelle (Event Target) verzeichnet sind.
Dann fährt der Bus los, verlässt das Depot und steuert die erste Haltestelle an.
Steht da nun ein Passagier der…
…dann steigt der Passagier in den Bus ein (die Callback-Funktion des Event Listeners wird also aufgerufen).
Steht dort kein potentieller Fahrgast, fährt der Bus auf seiner festgelegten Route einfach weiter in Richtung seines Ziels, und bei jeder Haltestelle (jedem Element auf dem Eventpfad) wiederholt sich die Prozedur.
An seiner Endhaltestelle angekommen dreht der Bus dann um und fährt wieder zurück zum Depot, wobei dann (in der Regel) wieder alle Haltestellen abgeklappert werden.
Dabei ist aber nun folgendes zu beachten: Nicht jedes Event verfügt über eine Bubbling-Phase!
Bestimmte Events, wie z.B. focus oder load haben von Natur aus nur zwei Eventphasen, nämlich die Capturing-Phase und die Target-Phase.
Das bedeutet, dass wenn man solche Events delegieren will, man sie in ihrer Capturing-Phase abfangen muss, sprich, man muss das optionale dritte Argument für die addEventListener
-Methode, deren Defaultwert false
ist, auf true
setzen:
document.addEventListener('focus', callback, true);
Hierbei ist zu beachten, dass, je nach dem welchen Wert die Capturing-Variable innehat und je nach dem ob das Event überhaupt bubbelt, die derart registrierten Event Listener nur entweder in ihrer Capturing-Phase oder in ihrer Bubbling-Phase ausgelöst werden.
Davon abgesehen ist aber noch interessant zu wissen, dass - um in unserem Beispiel zu bleiben - es nicht nur sein kann, dass der Bus von seiner Endhaltestelle (Event Target) direkt wieder zum Depot (Window) fährt, da es keine Bubbling-Phase gibt, sondern die Reise des Busses auch manuell unterbrochen werden kann, durch zwei Methoden der Event-Schnittstelle, nämlich stopPropagation( )
und stopImmediatePropagation( )
:
document.body.addEventListener('click', function (e) {
e.stopPropagation( ); // oder auch e.stopImmediatePropagation( );
});
Es ist also in etwa so, als wenn ein Fahrgast in den Bus einsteigt, dem Fahrer eine Knarre an die Rübe hält und anordnet, keine weiteren Haltestellen anzufahren (stopPropagation), sprich, keine Event Listener mehr auszulösen, die für andere Elemente registriert sind, als für dasjenige, welches als e.currentTarget
hinterlegt ist.
Oder im Falle von stopImmediatePropagation( )` auch an dieser Haltestelle keine weiteren Fahrgäste mehr einsteigen zu lassen, also überhaupt keine anderen Event Listener mehr auszulösen, nicht nur bei anderen Elementen nicht, sondern auch keinen weiteren, für diesen Event-Typ in der mit dem Current Target assoziierten Liste von Event Listenern hinterlegten Handler mehr auszulösen.
Über das Geschriebene hinaus stellt die Schnittstelle Event noch weitere Eigenschaften und Methoden bereit, die ich aus Platzgründen hier jedoch nicht beschreibe, zumal das alles ja auch anderswo nachgelesen werden kann.
Zu erwähnen sei hier höchstens noch die Methode e.preventDefault
, mit der sich, so dies grundsätzlich im Einzelfall möglich ist, die Ausführung einer Defaultaktion des User Agents aussetzen lässt. Ob dies möglich ist, kann über die Eigenschaft e.cancelable
in Erfahrung gebracht werden.
Also das war jetzt eine Menge Text, aber wirklich schwer zu verstehen ist es eigentlich nicht.
Hoffe ich. ;-)
Gruß,
Orlok
Lieber Orlok,
Also das war jetzt eine Menge Text, aber wirklich schwer zu verstehen ist es eigentlich nicht.
und jetzt noch ins Wiki damit... ;-)
Liebe Grüße,
Felix Riesterer.
Wahnsinnserklärung! Könntest du daraus einen Wiki-Artikel machen? Damit würdest du mir und Matthias Scharwies, der mich mal gebeten hat, diesen Artikel zu schreiben, eine riesige Freude bereiten. Ich komm leider momentan selber nicht dazu.
Servus!
Das wäre super! Der Beitrag würde hier passen: JavaScript/Objekte/DOM/event
Vielen Dank im Voraus!
Matthias Scharwies
Hallo
Wahnsinnserklärung! Könntest du daraus einen Wiki-Artikel machen? Damit würdest du mir und Matthias Scharwies, der mich mal gebeten hat, diesen Artikel zu schreiben, eine riesige Freude bereiten.
Das hat Felix ja schon aufgebracht, der an dieser Stelle auch ganz lieb gegrüßt sei. ;-)
In der Tat ist mir bei der Lektüre des Wikis schon aufgefallen, dass da insbesondere in der JavaScript-Sektion, vorsichtig formuliert, einiges im Argen liegt, und ganz besonders im Hinblick auf Events und Eventverarbeitung…
Ich meine, schon die strukturelle Aufteilung ist einigermaßen unglücklich:
Denn dadurch, dass die einzelnen Events unter der Rubrik Event-Handler aufgelistet sind, statt direkt unter Events, entsteht einerseits der fatale Eindruck, dass diese Methode der Eventverarbeitung der allgemeine Standard wäre, was dazu führt, dass die in der letztgenannten Rubrik etwas versteckte addEventListener-Methode - wie man hier im Forum gut beobachten kann - weithin ignoriert wird…
…und andererseits führt dies dazu, dass die einzelen Events von den Benutzern mit den Handlern assoziiert werden, so dass man hier immer wieder sowas liest wie:
„Das onclick-Event…“ - was natürlich Quatsch ist.
Auch herrscht bei der Beschreibung der Methoden der Event-Schnittstelle einigermaßen Ebbe, zumal beispielsweise event.stopImmediatePropagation( )
gar nicht aufgeführt ist, und stopPropagation( ) und preventDefault( ) mit einem Einzeiler und ein paar weiterführenden Links abgespeist werden, um nur mal ein paar sehr augenscheinliche Defizite aufzuzählen…
Die Sache ist nur die, dass ich den Post hier eigentlich nur deswegen rausgehauen habe, da mir in einigen aktuellen Threads so manche Wissenslücke hinsichtlich der Eventverarbeitung aufgefallen war, und ich das Gefühl hatte, meine dort häppchenweise vorgetragenen Hinweise würden ignoriert. ;-)
Jedenfalls ist klar, dass auch dieser Post lediglich eine sehr grobe Zusammenfassung der Materie darstellt, und wenn man einen echten Artikel zu dem Thema schreiben wollte, dann müsste man hier noch sehr viel mehr Informationen hinzufügen, wie du sicher selbst weißt.
Womit wir bei…
Ich komm leider momentan selber nicht dazu.
…wären. ;-)
Für die nächsten zwei Wochen bin ich mit meinem Studium noch voll eingespannt und habe auch selbst absolut nicht die Zeit, mich dieser Aufgabe zu widmen, aber danach könnte ich mich durchaus mal dransetzen.
Zwar wollte ich eigentlich zuerst die Array-Sektion aufmöbeln, aber ich kann gerne das Eventhandling auf meiner Prioritätenliste fürs Wiki auf Platz 1 setzen und mich darum kümmern, sobald ich hier wieder etwas Luft zum atmen habe… ;-)
Gruß,
Orlok
Servus!
In der Tat ist mir bei der Lektüre des Wikis schon aufgefallen, dass da insbesondere in der JavaScript-Sektion, vorsichtig formuliert, einiges im Argen liegt, und ganz besonders im Hinblick auf Events und Eventverarbeitung…
Ja, das ist eine Riesenbaustelle, bei der oft auch die ToDos fehlen.
Ich meine, schon die strukturelle Aufteilung ist einigermaßen unglücklich:
Denn dadurch, dass die einzelnen Events unter der Rubrik Event-Handler aufgelistet sind, statt direkt unter Events,
Würdest Du das auf einer Seite alles zusammengefasst haben wollen?
@Felix Riesterer @1unitedpower @Matthias Apsel @dedlfix Was haltet Ihr davon?
Ich würde die Event-Handler gerne dort lassen, sie aber wie in den Referenzen alphabetisch ordnen und in solche Tabellen formatieren: Test-Wiki: JavaScript/Event-Handler/onclick
Auch herrscht bei der Beschreibung der Methoden der Event-Schnittstelle einigermaßen Ebbe, zumal beispielsweise
event.stopImmediatePropagation( )
gar nicht aufgeführt ist, und stopPropagation( ) und preventDefault( ) mit einem Einzeiler und ein paar weiterführenden Links abgespeist werden, um nur mal ein paar sehr augenscheinliche Defizite aufzuzählen…
Full ACK, bei einem ist wenigstens ein ToDo drin.
Zwar wollte ich eigentlich zuerst die Array-Sektion aufmöbeln, aber ich kann gerne das Eventhandling auf meiner Prioritätenliste fürs Wiki auf Platz 1 setzen und mich darum kümmern, sobald ich hier wieder etwas Luft zum atmen habe… ;-)
Eine Mitarbeit von Dir (und auch anderen) ist jederzeit willkommen!
Gruß,
Orlok
Herzliche Grüße
Matthias Scharwies
Hallo
Ich meine, schon die strukturelle Aufteilung ist einigermaßen unglücklich:
Denn dadurch, dass die einzelnen Events unter der Rubrik Event-Handler aufgelistet sind, statt direkt unter Events,
Würdest Du das auf einer Seite alles zusammengefasst haben wollen? […]
Ich würde die Event-Handler gerne dort lassen, sie aber wie in den Referenzen alphabetisch ordnen und in solche Tabellen formatieren […]
Nein, die „Event-Handler“ können bleiben wo sie sind, aber die unterschiedlichen Events sollten IMHO unter der gleichnamigen Rubrik aufgeführt sein.
Es gibt kein onload
-Event und erst recht kein onLoad
-Event, sondern nur einen load
-Eventtyp, ich meine, das ist genau die Art von Konfusion, auf die ich mit meiner Kritik hinweisen wollte… ;-)
Die Events sollten meiner Meinung nach von den Eventhandling-Methoden getrennt sein, statt, wie es im Moment ist, mit einer nicht zu empfehlenden Methode verknüpft zu sein.
Wenn man etwas zum 'click'-Event in Erfahrung bringen möchte sollte nicht das Erste was man sieht die folgende Zeile sein:
element.onclick = handler;
…und erst recht nicht wie hier als HTML-Attribut…
<button onclick="handler()"> Do it! </button>
U know what I mean?
Gruß,
Orlok
Servus!
Es gibt kein
onload
-Event und erst recht keinonLoad
-Event, sondern nur einenload
-Eventtyp, ich meine, das ist genau die Art von Konfusion, auf die ich mit meiner Kritik hinweisen wollte… ;-)Die Events sollten meiner Meinung nach von den Eventhandling-Methoden getrennt sein, statt, wie es im Moment ist, mit einer nicht zu empfehlenden Methode verknüpft zu sein.
Wenn man etwas zum 'click'-Event in Erfahrung bringen möchte sollte nicht das Erste was man sieht die folgende Zeile sein:
element.onclick = handler;
…und erst recht nicht wie hier als HTML-Attribut…
<button onclick="handler()"> Do it! </button>
U know what I mean?
Ja, stimmt!
Matthias Scharwies
@@Orlok
Wobei zu beachten ist, dass keine identischen Event Listener für ein Element existieren dürfen, sprich, wenn man für das gleiche Element mehr als einen Event Listener mit den selben Argumenten registriert, dann wird der bestehende Listeneintrag durch die nachfolgenden überschrieben. Aber das nur nebenbei.
Diese Nebenbemerkung hättest du dir verkneifen können. ;-) Da irrst du nämlich, glaub ich.
Eben da liegt der Unterschied. Hier wird überschrieben:
myElement.onclick = function () { console.log(1); };
myElement.onclick = function () { console.log(2); };
// Ausgabe:
// 2
Hier hingegen nicht:
myElement.addEventListener('click', function () { console.log(1); });
myElement.addEventListener('click', function () { console.log(2); });
// Ausgabe:
// 1
// 2
Gegenseitig überschreiben sich on…
und addEventListener
auch nicht:
myElement.addEventListener('click', function () { console.log(1); });
myElement.addEventListener('click', function () { console.log(2); });
myElement.onclick = function () { console.log(3); };
// Ausgabe:
// 1
// 2
// 3
Ebenso wie:
myElement.onclick = function () { console.log(1); };
myElement.addEventListener('click', function () { console.log(2); });
myElement.addEventListener('click', function () { console.log(3); });
// Ausgabe:
// 1
// 2
// 3
LLAP 🖖
Hallo
Wobei zu beachten ist, dass keine identischen Event Listener für ein Element existieren dürfen, sprich, wenn man für das gleiche Element mehr als einen Event Listener mit den selben Argumenten registriert, dann wird der bestehende Listeneintrag durch die nachfolgenden überschrieben. Aber das nur nebenbei.
Diese Nebenbemerkung hättest du dir verkneifen können. ;-) Da irrst du nämlich, glaub ich.
Von element.onclick
habe ich nichts geschrieben, da ich hoffte, durch konsequentes Ignorieren aller anderen Methoden die Leser dazu zu bringen, Events grundsätzlich mit der addEventListener
-Methode zu verarbeiten. ;-)
Ich zitiere mal:
„The addEventListener(type, callback, capture) method must run these steps:
If callback is null, terminate these steps.
Append an event listener to the associated list of event listeners with type set to type, callback set to callback, and capture set to capture, unless there already is an event listener in that list with the same type, callback, and capture.“
Wenn du eine anonyme Funktion als Callback-Argument übergibst, wird in Ermangelung eines Bezeichners zur Differenzierung vermutlich der Function-Body verglichen und…
console.log(1) !== console.log(2)
…weshalb hier nicht die selben Argumente übergeben wurden. ;-)
Geirrt habe ich aber trotzdem, da der erste Eintrag nicht überschrieben wird, sondern der zweite nicht hinzugefügt wird!
Gruß,
Orlok
@@Orlok
Wenn du eine anonyme Funktion als Callback-Argument übergibst, wird in Ermangelung eines Bezeichners zur Differenzierung vermutlich der Function-Body verglichen und…
console.log(1) !== console.log(2)
Sieht nicht so aus, denn
myElement.addEventListener('click', function () { console.log(1); });
myElement.addEventListener('click', function () { console.log(1); });
// Ausgabe:
// 1
// 1
Es sind immer noch unterschiedliche Funktionsobjekte[1].
Aber ich verstehe, worauf du hinauswillst:
function log1() { console.log(1); }
myElement.addEventListener('click', log1);
myElement.addEventListener('click', log1);
// Ausgabe:
// 1
LLAP 🖖
Ist das sprachlich korrekt? ↩︎
@@Gunnar Bittersmann
Wenn du eine anonyme Funktion als Callback-Argument übergibst …
Sieht nicht so aus
Und das auch nicht bei nicht anonymen Funktionen:
myElement.addEventListener('click', function log1() { console.log(1); });
myElement.addEventListener('click', function log1() { console.log(1); });
// Ausgabe:
// 1
// 1
LLAP 🖖
Hallo
Es sind immer noch unterschiedliche Funktionsobjekte.
Sind sie.
„the same callback“
Oh man, ich bin nicht mehr auf der Höhe…
Gruß,
Orlok
Hallo,
Es sind immer noch unterschiedliche Funktionsobjekte.
Ist das sprachlich korrekt?
kommt drauf an, was du wirklich meinst. Unterschiedlich heißt für mich verschiedenartig. Verschieden heißt möglicherweise gleichartig, aber nicht identisch.
So long,
Martin
Tach!
Kann es sein das Javascript mit der Raute innerhalb der href Anweisung nicht zurecht kommt.
Javascript hat damit kein Problem.
Der JavaScript code für die Accordions sieht wie folgt aus. Dieser funktioniert jedoch sehr gut solange ich alle Elemente statisch erzeuge.
Es gibt keinen Unterschied zwischen "dynamisch" und "statisch" erzeugten Elementen. Element ist Element. Es kann jedoch sein - sagt meine Glaskugel - dass du den Code aufrufst, und die Eventhandler an die Elemente zu binden versuchst, bevor du die Elemente erzeugst. Das kann dann so nicht klappen.
Entweder du setzt die Eventhandler nach dem Erzeugen der Elemente oder du bindest die Eventhandler an ein die ganze Zeit vorhandenes Vorfahren-Element und fängst dann die hochgebubbelten Events auf.
dedlfix.
Danke für die Antwort. Der Code für die Accordionevents sieht wie folgt aus. Dieser steht in einer eigenen Datei und wird über den script tag in die html datei eingebunden. Innerhalb der js Datei verwendet ich ja nur classNames wie accordion_section-title und accordion-section-content. Es werden also eigentliche keine Objekte direkt angesprochen.
$(document).ready(function() {
function close_accordion_section() {
$('.accordion .accordion-section-title').removeClass('active');
$('.accordion .accordion-section-content').slideUp(300).removeClass('open');
}
$('.accordion-section-title').click(function(e) {
// Grab current anchor value
$('.accordion input[type="checkbox"]').click(function(e) {
e.stopPropagation();
});
var currentAttrValue = $(this).attr('href');
if ($(e.target).is('.active')) {
close_accordion_section();
} else {
close_accordion_section();
// Add active class to section title
$(this).addClass('active');
// Open up the hidden content panel
$('.accordion ' + currentAttrValue).slideDown(300).addClass('open');
}
e.preventDefault();
});
});
Auf diese Weise wird der Click-Eventhandler nur einmal zum Document-Ready-Zeitpunkt den Elementen, die bis dahin existieren, zugewiesen. Wenn Du dann nachträglich dynamisch weitere Elemente hinzufügst, mußt Du denen den Event-Handler auch nochmal zuweisen.
Tach!
$(document).ready(function() {
Damit wird der Code genau einmal zum Zeitpunkt von DOM-ready ausgeführt. Alles was da noch nicht da ist, bekommt keinen Eventhandler - das passiert auch nicht automagisch in der Zukunft. Wie ich schon vermutete, musst du den Eventhandler nach dem Erzeugen der Elemente hinzufügen (oder das mit dem gebubbelten Event).
dedlfix.
@@bits
Jedoch will die verlinkung mit dem accordion content einfach nicht funktionieren.
„Funktioniert nicht“ als Problembeschreibung funktioniert nicht.
Was erwartest du? Was passiert stattdessen? Was sagt die Fehlerkonsole? Link zur fraglichen Seite?
LLAP 🖖
Ich erwarte ein übliches accordion verhalten. Also wenn man auf den accordion header klickt, geht ein content bereich nach unten auf und bei erneutem klicken wieder zu. Accordion eben ;-) Bei mir wird der header zwar angezeigt, wenn ich darauf klicke passiert nichts. Der accordion content wird nicht aufgeklapppt bzw angezeigt. Einen link zur Seite kann ich momentan nicht liefern. Die seite wird aktuell nur lokal betrieben
Tach!
Ich erwarte ein übliches accordion verhalten.
Das ist das was der Anwender erwartet. Du bist aber der Programmierer, und als solcher musst du weiter ins Details gehen und beschreiben, was du auf Code-Ebene erwartest. Und was du bereits mit den eingebauten Debugging-Werkzeugen oder auch anderswie ermittelt hast.
dedlfix.