onclick funktioniert nicht auf Smartphone
Linuchs
- browser
- javascript
Hallo,
bisher habe ich geschaut, ob gewisse Webseiten auf dem Smartphone ordentlich aussehen. Aber noch nie habe ich mit dem Smartphone Ajax-Verbindungen getestet. Und prompt funktioniert es auch nicht.
Auf einem Formular sind Namen anzuklicken. Jeder Klick bewirkt per Ajax einen Eintrag in die Datenbank. Bei nochmaligem click wird der Eintrag wieder gelöscht.
Ein bestehender Eintrag wird durch gelbe Hintergrund-Farbe angezeigt.
Klappt vorzüglich auf dem PC unter Firefox, aber nicht mit meinem Android-Browser.
Ich vermute, ein Smartphone versteht die Anweisung onclick nicht. Oder was kann das sein?
Und ja - ich habe vor einer Woche eine Lektion in Event-Handling bekommen, aber nicht verstanden, wie ich den "Absender" des onclick-Events erkenne. Das feuert ja in allen übergeordneten Tags.
Bitte diese Seite mal mit dem Smartphone aufrufen. Ich kann keinen Namen akivieren.
Linuchs
Hallo Linuchs,
Wenn das so aussehen soll, wie im Anhang, scheint es bei mir auf Android 5 mit mBrowser, Firefox und Chrome (jeweils die aktuellsten Versionen) keine Probleme zu geben.
Gruß
Julius
Hallo Julius,
Wenn das so aussehen soll, wie im Anhang, scheint es bei mir auf Android 5 mit mBrowser, Firefox und Chrome (jeweils die aktuellsten Versionen) keine Probleme zu geben.
Ja, so soll es aussehen. Du hast mit dem Finger auf einen Namen getippt und der wurde sofort gelb unterlegt?
Ich habe nochmal auf meinem Smartphone getestet. Die Namen werden gewählt, was ich mit dem PC überprüft habe, aber nicht gelb hinterlegt. Beim nächsten Klick wird die Wahl wieder storniert. Die Rückmeldung klappt also nicht.
Also empfängt mein Smartphone die Ajax-Rückmeldung nicht oder zeigt die Hintergrund-Farbe nicht an.
Gruß, Linuchs
Hallo Linuchs,
Ja, so soll es aussehen. Du hast mit dem Finger auf einen Namen getippt und der wurde sofort gelb unterlegt?
Ja, unverzüglich.
Gruß
Julius
@@Julius
Ja, unverzüglich
Auf’m iPhone auch.
LLAP 🖖
Hallo Linuchs
Und ja - ich habe vor einer Woche eine Lektion in Event-Handling bekommen, aber nicht verstanden, wie ich den "Absender" des onclick-Events erkenne. Das feuert ja in allen übergeordneten Tags.
Ich weiß, dass ich nicht besonders gut im Erklären bin, der von dir angesprochene Thread ist dafür ein trauriges Beispiel. In dieser Hinsicht wäre es aber auch für mich hilfreich gewesen, wenn du nochmals nachgefragt und dabei die einzelnen Stellen angesprochen hättest, die du nicht verstanden hast.
Mit „Absender“ des Ereignisses meinst du wohl das Element, bei dem das Ereignis eingetreten ist:
Das ist das Ziel (Target) des Ereignisses.
Wenn du das Objekt referenzieren willst, welches das Ziel eines Ereignisses ist, dann kannst du dies über die Eigenschaft target
des Event-Objektes machen:
<body>
<ul id="list">
<li>A</li>
<li>B</li>
<li>C</li>
</ul>
<script>
document.getElementById('list').addEventListener('click', function (event) {
if (event.target !== this) {
console.log(event.target.textContent); // A oder B oder C
}
});
</script>
</body>
Hier ist ein Eventhandler für das Objekt registriert, welches das ul
-Element mit der ID list
repräsentiert, und zwar für das Ereignis click
. Dieser Eventhandler wird nun immer dann aufgerufen wenn entweder auf das Listenelement selbst, oder aber auf eines seiner Kindelemente geklickt wird.
Für die anonyme Funktion die wir der Methode addEventListener
hier als zweites Argument übergeben ist ein Parameter event
deklariert. Wenn nun die Funktion bei einem Klick innerhalb der Liste aufgerufen wird, dann wird bei diesem Aufruf das Event-Objekt als Argument übergeben, sodass dieses innerhalb der Funktion über event
referenziert werden kann.
Der Wert der Eigenschaft target
des Event-Objektes ist nun wie gesagt immer eine Referenz auf das Objekt, bei dem das Ereignis eingetreten ist. Das bedeutet, hier im Beispiel verweist event.target
entweder auf das Listenelement selbst, für das wir den Eventhandler registriert haben, oder aber auf eines der Kindelemente der Liste, eben abhängig davon, auf welches der Elemente tatsächlich geklickt wurde.
Die Variable this
hingegen, ebenso wie die Eigenschaft event.currentTarget
enthält immer eine Referenz auf das Objekt für welches der aufgerufene Eventhandler registriert wurde. Wenn wir also prüfen
if (event.target !== this)
dann heißt das soviel wie: „Wenn das Element auf das geklickt wurde nicht das Element ist, für das dieser Eventhander registriert wurde, dann führe die folgende Anweisung aus.“
Wir hätten an dieser Stelle also ebenso gut schreiben können
if (event.target !== event.currentTarget)
oder auch
if (event.target !== document.getElementById('list'))
Da wir das Element ul
, für welches wir den Handler registriert haben, durch diese bedingte Anweisung ausgeschlossen haben, wird also nur dann der textuelle Inhalt des Zielobjektes in die Konsole geschrieben, wenn auf eines der li
-Elemente geklickt wurde. Sonst passiert nichts.
console.log(event.target.textContent); // A oder B oder C
Das meinte ich im Übrigen mit „in der Handlerfunktion selektieren“: Den Wert der Eigenschaft target
des Event-Objektes lesen und dann abhängig von dem dort referenzierten Zielobjekt die verschiedenen Anweisungen ausführen.
Drehen wir unser Beispiel einmal um und nehmen an, wir wollten nur dann etwas machen, wenn das Ereignis tatsächlich bei dem ul
-Element aufgetreten ist, nicht aber bei einem seiner Kindelemente:
<body>
<ul id="list">
<li>A</li>
<li>B</li>
<li>C</li>
</ul>
<script>
document.getElementById('list').addEventListener('click', function (event) {
if (event.target.parentElement === document.body) {
console.log(event.target.tagName); // UL
}
});
</script>
</body>
Auch hier ist wieder ein Eventhandler für das ul
-Element mit der ID list
registriert, und auch hier verwenden wir event.target
, um das Element zu identifizieren, auf das tatsächlich geklickt wurde.
if (event.target.parentElement === document.body) {
console.log(event.target.tagName); // UL
}
Hier prüfen wir, ob das Elternelement des Elementes auf das geklickt wurde das body
-Element ist. Da das Elternelement der li
-Elemente hier natürlich nicht body
sondern ul
ist, wird die nachfolgende Anweisung nur ausgeführt, wenn auf das Listenelement selbst geklickt wurde.
Wobei wir bezogen auf dieses konkrete Beispiel freilich besser so geprüft hätten (siehe oben):
if (event.target === this)
// oder
if (event.target === event.currentTarget)
Wandeln wir das Beispiel nochmals etwas ab, sodass es dem Code recht ähnlich ist, den du im ersten Beitrag des eingangs verlinkten Threads gepostet hattest:
<body>
<ul id="list">
<li>A</li>
<li>B</li>
<li>
<ul class="sub">
<li>C</li>
<li>D</li>
</ul>
</li>
</ul>
<script>
document.getElementById('list').addEventListener('click', function (event) {
var target = event.target, parent = target.parentElement;
if (parent === this && !target.children[0]) {
console.log('click on list level one item');
}
else if (parent.className === 'sub') {
console.log('click on list level two item');
}
});
</script>
</body>
Auch hier wird wieder über event.target
selektiert:
Die erste bedingte Anweisung wird nur dann ausgeführt, wenn auf ein Kindelement von list
geklickt wurde, das nicht selbst über ein Kindelement verfügt. Hier also die ersten beiden li
-Elemente mit dem Inhalt A
und B
. Die zweite bedingte Anweisung wird entsprechend nur dann ausgeführt, wenn auf eines der beiden Kindelemente des zweiten ul
-Elementes mit der Klasse sub
geklickt wurde.
Hierbei sei übrigens besonderes Augenmerk auf den zweiten Teil der ersten Bedingung gerichtet:
Im Gegensatz zu deinem Beispielcode habe ich hier nicht die Eigenschaft childNodes
gelesen sondern die Eigenschaft children
. In childNodes
sind nämlich anders als in children
nicht nur Elementknoten enthalten sondern ebenfalls Textknoten, und das hätte uns hier natürlich nicht weitergeholfen.
Das wäre nun jedenfalls ein Beispiel für das Prinzip der Event Delegation, denn die Behandlung von Ereignissen, die bei verschiedenen Elementen eintreten, wird hier an eine einzige Handlerfunktion delegiert, welche für ein gemeinsames Elternelement registriert wurde.
Ich hoffe ich konnte dir nun zumindest diesen Punkt verständlich machen. Wenn nicht, wirst du dir wohl jemanden suchen müssen der das besser erklären kann als ich. :-/
Viele Grüße,
Orlok
Hallo Orlok,
Ich weiß, dass ich nicht besonders gut im Erklären bin, der von dir angesprochene Thread ist dafür ein trauriges Beispiel.
Das finde ich ganz und gar nicht.
In dieser Hinsicht wäre es aber auch für mich hilfreich gewesen, wenn du nochmals nachgefragt und dabei die einzelnen Stellen angesprochen hättest, die du nicht verstanden hast.
Dem stimme ich allerdings voll und ganz zu. Manchmal ist in solchen Fragen ein Forum allerdings auch schlichtweg das falsche Medium.
Bis demnächst
Matthias
Hallo Orlok,
gute Fachleute müssen nicht automatisch gute Lehrer sein. Dieses kleine Beispiel von dir finde ich prima, werde es einsetzen und ausbauen:
<body> <ul id="list"> <li>A</li> <li>B</li> <li>C</li> </ul> <script> document.getElementById('list').addEventListener('click', function (event) { if (event.target !== this) { console.log(event.target.textContent); // A oder B oder C } }); </script> </body>
Und dann nach und nach deinen Roman verstehen. Danke dir.
Linuchs
@@Linuchs
Klappt vorzüglich auf dem PC unter Firefox
Nein, das tut es nicht.
Bitte diese Seite mal mit dem Smartphone aufrufen. Ich kann keinen Namen akivieren.
Bitte diese Seite mal mit beliebigem Gerät aufrufen. Ich kann keinen Namen akivieren. Nicht per Tastatur. Deine Auswahl ist nicht funktionstüchtig.
Bevor du jetzt rangehst und die Tastaturbedienbarkeit mühsam mit JavaScript und ARIA nachrüstest: das ist nicht der Weg, du du gehen solltest. Sondern: die richtigen HTML-Elemente verwenden: Du willst eine Ja/nein-Auswahl von mehreren Items – also Checkboxen.
Nicht
<div id="K13778-14649" onclick="toggleWunsch( '14649', this)" class="border_transparent prio1 haken1 fleet" title="4Fleet Group 50733 Köln Kontakt 13778-14649">
<p class="bezeichnung">4Fleet Group</p>
</div>
sondern
<div>
<input type="checkbox" id="K13778-14649" name="K13778-14649"/>
<label for="K13778-14649" title="4Fleet Group 50733 Köln Kontakt 13778-14649">4Fleet Group</label>
</div>
oder auch
<label>
<input type="checkbox" name="K13778-14649"/>
<span title="4Fleet Group 50733 Köln Kontakt 13778-14649">4Fleet Group</span>
</label>
Damit ist die Tastaturbedienbarkeit gegeben. Und die Auswahl funktioniert auch ohne JavaScript. Du kannst natürlich Funktionalität als progressive enhancement hinzufügen.
Und du kannst die Auswahl wie gewünscht stylen: ausgewählte Items gelb hinterlegt:
:checked + label { background: yellow }
bzw.
:checked + span { background: yellow }
LLAP 🖖