onclick Event Handler
Stefan
- javascript
Hallo alle zusammen :)
Ich habe folgendes Problem:
Ich habe eine tabelle mit einem onclick versehen.
Besser gesagt eine Zeile.
<table>
<tr onclick="blab();">
<td>
</td>
</tr>
</table>
Jedoch befinden sich in dieser Zelle auch Links:
<table>
<tr onclick="blab();">
<td>
<a href="#">Link A</a><br>
<a href="#">Link B</a><br>
</td>
</tr>
</table>
Wenn ich jetzt auf den Link klicke wird die onclick-Funktion auch mit ausgeführt.
Gibt es eine Möglichkeit die onclick-Funktion NUR dann auszuführen wenn ich in der Zelle nicht auf einen Link klicke?
Hoffen auf baldige Anwort,
Stefan
Ahoi,
entweder, in dem du den event mit einem Script zuweist nachdem die Seite geladen wurde (nach onload alle tr-Elemente daraufhin untersuchen, ob darin ein anker ist, und wenn nicht, dann tr.onload = blub zuweisen).
oder innerhalb der funktion kommst du vielleicht an das callende Element heran.
Dank und Gruß,
Ahoi,
entweder, in dem du den event mit einem Script zuweist nachdem die Seite geladen wurde (nach onload alle tr-Elemente daraufhin untersuchen, ob darin ein anker ist, und wenn nicht, dann tr.onload = blub zuweisen).
Ich will allerdings dann die onclick Funktion ausgeführt wird wenn ich ins <tr> Element klicke, jedoch nicht wenn ich auf den Link klicke (der sich leider innerhalb des Elements befindet)
oder innerhalb der funktion kommst du vielleicht an das callende Element heran.
Dank und Gruß,
Möglich?
Ahoi,
ich weiß nicht, ob in der funktion der caller so mir-nichts-dir-nichts vorhanden ist. immerhin könntest du "this" übergeben:
<table>
<tr id="test" onclick="alert(this.id + ' - ' + this.getElementsByTagName('a').length)"><td><p>blub</p></td></tr>
<tr id="test" onclick="alert(this.id + ' - ' + this.getElementsByTagName('a').length)"><td><a>blub</a></td></tr>
</table>
Dank und Gruß,
[latex]Mae govannen![/latex]
Wenn ich jetzt auf den Link klicke wird die onclick-Funktion auch mit ausgeführt.
Gibt es eine Möglichkeit die onclick-Funktion NUR dann auszuführen wenn ich in der Zelle nicht auf einen Link klicke?
Du kannst das geklickte Element ermitteln und wenn dieses ein a-element ist, das Eventbubbling verhindern
Cü,
Kai
[latex]Mae govannen![/latex]
Du kannst das geklickte Element ermitteln und wenn dieses ein a-element ist, das Eventbubbling verhindern
sollte
... und wenn dieses ein a-element ist, ...
heißen ;)
Cü,
Kai
Ahoi,
Du kannst das geklickte Element ermitteln und wenn dieses ein a-element ist, das Eventbubbling verhindern
Insofern ist also in der Funktion "this" das Element, in dem der Click ausgeführt wurde?
Dank und Gruß,
[latex]Mae govannen![/latex]
Insofern ist also in der Funktion "this" das Element, in dem der Click ausgeführt wurde?
Nein. Der Event-Listener ist ja dem tr-Element zugewiesen:
<tr onclick="bla()"><td><a href="#">Link</a></td></tr>
function bla() {
alert(this);
}
hier würde this
auf das globale Objekt (window) zeigen
Wird this
hingegen übergeben:
<tr onclick="bla(this)"><td><a href="#">Link</a></td></tr>
ist in der Funktion
function bla(ref) {
alert(ref.nodeName);
}
in ref immer die Referenz auf das tr-Element übergeben, egal, was innerhalb angeklickt wird.
Also: so geht es nicht. Daher muß in der Funktion bla das geklickte Element mit target bzw. srcElement ermittelt werden:
<tr onclick="bla()"><td><a href="#">Link</a></td></tr>
function bla(e) {
if (!e) e = window.event;
var ref = e.target || e.srcElement;
alert(ref.nodeName);
}
Cü,
Kai
Also: so geht es nicht. Daher muß in der Funktion bla das geklickte Element mit target bzw. srcElement ermittelt werden:
<tr onclick="[code lang=javascript]bla()
"><td><a href="#">Link</a></td></tr>[/code]
function bla(e) {
if (!e) e = window.event;
var ref = e.target || e.srcElement;
alert(ref.nodeName);
}
Du hast vergessen, das Ereignis zu übergeben:
`<tr onclick="[code lang=javascript]bla(arguments[0]);`{:.language-html}">...</tr>[/code]
--
Reden ist Silber, Schweigen ist Gold, meine Ausführungen sind Platin.
Self-Code: sh:( ch:? rl:( br:> n4:( ie:{ mo:) va:) de:> zu:} fl:| ss:| ls:~ js:|
Ahoi,
»» Insofern ist also in der Funktion "this" das Element, in dem der Click ausgeführt wurde?
Nein. Der Event-Listener ist ja dem tr-Element zugewiesen:
<tr onclick="bla()"><td><a href="#">Link</a></td></tr>
function bla() {
alert(this);
}
>
> hier würde `this`{:.language-javascript} auf das globale Objekt (window) zeigen
>
>
> Wird `this`{:.language-javascript} hingegen übergeben:
>
> <tr onclick="bla(this)"><td><a href="#">Link</a></td></tr>
>
> ist in der Funktion
>
> ~~~javascript
function bla(ref) {
> alert(ref.nodeName);
> }
in ref immer die Referenz auf das tr-Element übergeben, egal, was innerhalb angeklickt wird.
Also: so geht es nicht. Daher muß in der Funktion bla das geklickte Element mit target bzw. srcElement ermittelt werden:
<tr onclick="bla()"><td><a href="#">Link</a></td></tr>
function bla(e) {
if (!e) e = window.event;
var ref = e.target || e.srcElement;
alert(ref.nodeName);
}
mmh,
~~~html
<script type="text/javascript">
window.onload = function() {
set_onclicks();
}
set_onclicks = function () {
divs = document.getElementsByTagName("div");
for(i=0;i<divs.length;i++) {
divs[i].onclick = test_click;
}
}
test_click = function () {
alert(this.id);
}
</script>
<div id="div1id">div1id</div>
<div id="div2id">div2id mit Anker:<a id="anker_id" >Anker mit anker_id</a></div>
<table>
<tr id="test" onclick="alert(this.id + ' - ' + this.getElementsByTagName('a').length)"><td><p>blub</p></td></tr>
<tr id="test" onclick="alert(this.id + ' - ' + this.getElementsByTagName('a').length)"><td><a>blub</a></td></tr>
</table>
in o.g. Beispielen ist jeweils "this" das aufrufende Element. Sowohl beim div, dem nach onload das onclick zugewiesen wird, wie auch das alert direkt im Quelltext.
--- Syntaxhighlight sieht komisch aus, ist aber getestet bzw. "funzt".
Dank und Gruß,
[latex]Mae govannen![/latex]
<table>
<tr id="test" onclick="alert(this.id + ' - ' + this.getElementsByTagName('a').length)"><td><p>blub</p></td></tr>
<tr id="test" onclick="alert(this.id + ' - ' + this.getElementsByTagName('a').length)"><td><a>blub</a></td></tr>
</table>
>
> in o.g. Beispielen ist jeweils "this" das aufrufende Element. Sowohl beim div, dem nach onload das onclick zugewiesen wird, wie auch das alert direkt im Quelltext.
`this`{:.language-javascript} ist hier \_immer\_ das Element, an das die Eventverarbeitung angehängt wurde, nicht das Element, das tatsächlich geklickt wurde. Wenn du im obigen Beispiel this.id durch this.nodeName ersetzt, wirst du immer tr erhalten, egal, ob du in die Zelle td, den Absatz p oder den Anker a klickst. Um das zu unterscheiden, muß das eigentliche Element über die target bzw. sourceElement-Eigenschaft des Eventobjektes ermittelt werden.
Cü,
Kai
--
„It's 106 miles to Chicago, we got a full tank of gas, half a pack of cigarettes, it's dark, and we're wearing sunglasses“.
„Hit it!“
[Selfzeugs](http://kaichen.in/selfhtml/)
SelfCode: sh:( fo:| ch:? rl:( br:< n4:( ie:{ mo:| va:) js:| de:> zu:) fl:( ss:| ls:?
Ich glaube, ihr redet aneinander vorbei. Lies dir nochmal den Unterschied zwischen Zielelement und verarbeitenden Element durch:
http://redaktion.selfhtml.org/selfhtml-preview/javascript/einbindung.html#bubbling
http://redaktion.selfhtml.org/selfhtml-preview/javascript/einbindung.html#currenttarget-target
Beispiel:
<tr onclick>
<td>
<p>blub</p>
</td>
</tr>
Wenn man hier auf das p klickt und tr einen click-Handler hat, dann gilt:
<tr onclick> ← Verarbeitendes Element (in der Bubbling-Phase)
<td>
<p>blub</p> ← Zielelement
</td>
</tr>
Im Handler kann man auf die beteiligten Elemente wie folgt zugreifen:
<tr onclick> ← this bzw. e.currentTarget gemäß DOM Events
<td>
<p>blub</p> ← e.target gemäß DOM Events bzw. e.srcElement im IE
</td>
</tr>
Mathias
Ahoi,
Ich glaube, ihr redet aneinander vorbei. Lies dir nochmal den Unterschied zwischen Zielelement und verarbeitenden Element durch:
http://redaktion.selfhtml.org/selfhtml-preview/javascript/einbindung.html#bubbling
http://redaktion.selfhtml.org/selfhtml-preview/javascript/einbindung.html#currenttarget-targetBeispiel:
<tr onclick>
<td>
<p>blub</p>
</td>
</tr>Wenn man hier auf das p klickt und tr einen click-Handler hat, dann gilt:
<tr onclick> ← Verarbeitendes Element (in der Bubbling-Phase)
<td>
<p>blub</p> ← Zielelement
</td>
</tr>Im Handler kann man auf die beteiligten Elemente wie folgt zugreifen:
<tr onclick> ← this bzw. e.currentTarget gemäß DOM Events
<td>
<p>blub</p> ← e.target gemäß DOM Events bzw. e.srcElement im IE
</td>
</tr>
Wobei der Funktion das Event aber immer als "arguments[0]" übergeben werden muss?
<tr onclick="blub(arguments[0])"> ?
Dank und Gruß,
Wobei der Funktion das Event aber immer als "arguments[0]" übergeben werden muss?
Wenn man mit Inline-Event-Handlern im HTML arbeitet: ja.
Wenn man die Ereignis-Überwachung mit JavaScript vornimmt, siehe Zugriff auf das Event-Objekt.
<tr onclick="blub(arguments[0])"> ?
Ja, oder onclick="blub(event)". (Ich kenne das arguments[0] nur von Timo und würde event empfehlen. Im Prinzip sind sie identisch, event ist der Name des erste Parameters, den die Handlerfunktion, die durch den Inline-Event-Handler erzeugt wurde, entgegennimmt.)
Mathias
<tr onclick="blab(event)">
function blab (e) {
var target = e.target || e.srcElement;
if (target.nodeName == "A") return;
// verarbeite Ereignis
}
oder wie gesagt die Handler-Registrierung aus dem HTML auslagern:
window.onload = function () {
document.getElementById("bla").onclick = function (e) {
var e = e || window.event;
// weiter wie oben
};
};
Mathias
Hi
der Ansatz ist gut, aber es könnte noch eine Schwachstelle geben. Wenn der Link weitere Kindnoten enthält, und diese angeklickt werden, wird der Code trotzdem ausgeführt. Man müsste also in einer Schleife alle Knoten die dazwischen liegen durchgehen.
function blab (e)
{
var el = e.target || e.srcElement;
while(el!=this)
{
if(el.nodeName == "A")
return;
el = el.parentNode;
}
// verarbeite Ereignis
}
mfg
Felix