JS onclick-element mittels Funktion definieren

nietaL

NGBler
Registriert
8 Sep. 2013
Beiträge
231
Ort
Exilgullianer
ich hoffe, ich darf noch Fragen stellen :D

Ein Link hat ein onclick-Element, das eine Funktion aufruft. Diese Funktion beinhaltet am Ende einen Code, der das anfängliche on-click element neu definiert. Soweit das Ziel

document.getElementById(idnr).onclick = "alert('hallo');"
document.getElementById(idnr).onclick = "alert(\'hallo\');"
document.getElementById(idnr).onclick = alert('hallo');"

Alles führt nicht dazu, dass beim zweiten Klick auf obig genanntes Element eine Alert entsteht. Ich glaube, es hat was mit der Maskierung zu tun. Die Syntax ist mir in diesem Fall nicht ganz klar :confused:
 
  • Thread Starter Thread Starter
  • #3
oha, okay, darauf wäre ich jetzt nicht gekommen. Kann ich die Funktion auch ausgelagert definieren, falls sie über alert() hinausgeht?

[src=javascript]function f1()
{
alert('hallo');
}

document.getElementById(idnr).onclick = f1(); [/src]

Das klappt leider nicht. Er führt sofort die f1 aus. :unknown:

--- [2016-03-31 22:53 CEST] Automatisch zusammengeführter Beitrag ---

okay, die Frage war peinlich... :m

[src=javascript]document.getElementById(idnr).onclick = function(){f1();};[/src]

danke für den Denkanstoß.
 
Du kannst deine erste Methode auch nutzen, dein fehler ist aber das du mit "()" die Funktion sofort "ausführst".
[src=javascript]
document.getElementById(idnr).onclick = f1();
// richtig wäre:
document.getElementById(idnr).onclick = f1;
[/src]
Bei der Möglichkeit, die du noch gefunden hast

[src=javascript]
document.getElementById(idnr).onclick = function(){
f1();
}
[/src]

besteht das Problem, das du den Context und die Event Parameter nicht mitgibst.

[src=javascript]
// auch onclick ist ein event, übergibt also den event parameter
document.getElementById(idnr).onclick = function( event ){
// ich rufe hiermit die f1 funktion auf, diese steht in dem Kontext von this
// this ist in dem fall das element "document.getElementById(idnr)"
// es wäre auch möglich einen anderen context mitzugeben
// zusätzlich übergebe ich den parameter event, welcher manchmal ganz nützlich sein kann ;)
f1.call( this, event);
}

function f1( ) {
console.log( arguments );
// sollte etwas ähnliches wie [MouseEvent] ausgeben
}
[/src]


Versuch onclick zu vermeiden, baue lieber einen ordentlichen EventListener auf. Beim Selektieren der Elemente empfehle ich eher "querySelector" oder "querySelectorAll".
Ich persönlich habe mir angewöhnt JS methodic nicht mit CSS- Klassen (oder ID´s) zu mischen, das führt zu unnötigen Abhängigkeiten.

[src=html5]
<a href="#" class="foo" data-handler="foo">klick 1</a>
[/src]

[src=javascript]
// möglich wäre ein selektieren der class '.foo'
// var $el = document.querySelectorAll('.foo');
// besser ist es aber den data-handler zu verwenden
var $el = document.querySelectorAll('*[data-handler="foo"]');

// auf das erste Element einen klickHandler erstellen
$el[0].addEventListener( 'click', elementClicked );

// funktion für den handler
function elementClicked( event ) {
event.preventDefault();
alert('hey');
}
[/src]

Diese Funktion beinhaltet am Ende einen Code, der das anfängliche on-click element neu definiert.

Dieser aussage kann ich nicht ganz folgen, definierst du nur die Funktionalität um, oder willst du auch das DOM element (HTML) neu erstellen? Dann muss der EventHandler entweder neu erzeugt werden, oder ein bisschen anders aufgebaut werden!
 
f1(); führt die Funktion f1 aus.
Mit f1; referenzierst du nur die Funktion f1.

Ein Beispiel:
[src=javascript]function f1(){ alert('Schreibe 42'); return 42; }
document.getElementById(idnr).onclick = f1(); // f1 wird sofort ausgeführt und die Rückgabe wird gebunden, also onclick = 42
document.getElementById(idnr).onclick = f1; // die Funktion f1 wird gebunden, onclick = function(){...}[/src]


State of the art wäre übrigens:

[src=javascript]function f1(){alert('hallo');}

var myObj = document.getElementById(idnr);
myObj.addEventListener('click', f1);
[/src]

Natürlich solltest du vorher feststellen, ob document.getElementById(idnr) tatsächlich existiert.
Einen querySelector halte ich in deinem Fall für ein wenig overkill. Aber prinzipiell hat KingJamez schon Recht.
 
Wenn du einen Click-Event mit einer anonymous Function zuweist, so wie Virtus es weiter oben beschrieben hat, musst du auch darauf achten, Events nicht versehentlich mehrfach zuzuweisen.

[src=javascript]
document.getElementById("button").addEventListener('click', function()
{
alert("i show up twice");
});

document.getElementById("button").addEventListener('click', function()
{
alert("i show up twice");
});
[/src]

Hingegen, wenn die Funktion direkt zugwiesen wird, wird die erste Zuweisung discarded und der Event trotz mehrmaliger Zuweisung nur einmal ausgeführt.

[src=javascript]
document.getElementById("button").addEventListener('click', bli);
document.getElementById("button").addEventListener('click', bli);

function bli()
{
alert("only once");
}
[/src]

Wenn nichts gegen ein zusätzliches Library spricht, würd ich empfehlen jQuery zu verwenden. Ich finde die Auswahl von Elementen und Event-Zuweisung ist damit übersichtlicher.
 
Naja, in #2 verwendest du eine anonymous function. Ist eh korrekt, wollt nur den Unterschied der zwei Varianten noch betonen.
 
  • Thread Starter Thread Starter
  • #9
Wow, ich habe nicht damit gerechnet, dass noch soviel zu ergänzen ist. :D Also ich musste es mir dreimal durchlesen, aber jetzt habe ich es verstanden. Nur eines nicht so recht:
In welcher Situation könnte das Verbinden von CSS und JS zu Problemen führen? Denn selbst bei virtus state of the art wird ja die IDNR verlangt (Post #5).
Und was ist bei onclick so nachteilhaft?

Danke soweit für die Tipps!! :beer:
 
In welcher Situation könnte das Verbinden von CSS und JS zu Problemen führen?
Unachtsame Veränderungen. Du willst CSS wieder verwenden und hast plötzlich einen Listener an einem Element hängen, an dem nichts zu suchen hat. Du machst ein Redesign und das Javascript fällt dir auseinander. Nach dem du zwei mal auf die Nase gefallen bist achtest du mehr auf diese Wechselwirkung und vergeudest damit Zeit, denn sie hat eigentlich keinen Zweck in deinem Projekt.
Diese Problematik ist bei Selektoren gegen class noch offensichtlicher.
CSS legt fest, wie das Element aussieht, JavaScript wie es sich verhält. Die Frage ist eher: In welcher Situation möchte man eine gemeinsame Abhängigkeit zu einem Attribut des Elements?


Dem onclick-Attribut kannst du nur genau eine Funktion zuweisen. EventListener kannst du hinzufügen bis dir der Speicher ausgeht [SUP][Citation needed][/SUP]. Vorteil von letzterem ist, dass du zum Beispiel die Button-Logik sauber vom Click-Tracking trennen kannst. Beide wollen auf das click-Event reagieren, haben aber nichts miteinander zu tun.
 
Spontan: Spoiler
Bei Klassen macht das gewöhnlich sogar Sinn, ein Element einer bestimmten Klasse bindet gewöhnlich stets sowohl Aussehen, als auch Funktion.
Allerdings stimmt es natürlich, dass es nicht immer sinnvoll ist an eine hardcoded ID zu binden. Er bezieht seine ID wohl dynamisch, daher sollte das eher unproblematisch sein.

@drfuture: Uneindeutige IDs wären allerdings auch wider allgemeingültiger Konventionen.

Mir ging es nicht darum, wie du das Element selektierst, welches du verwendest, sondern darum, wie du die Funktion bindest.
 
Zurück
Oben