4 Stimmen

Umfang einer Javascript-Variable in der anonymen Funktion addEventListener

Beim Anklicken der einzelnen Divs soll die Meldung "1" erscheinen, wenn Div 1 angeklickt wurde, oder "5", wenn Div 2 angeklickt wurde. Ich habe versucht, diesen Code so einfach wie möglich zu machen, weil dies in einer viel größeren Anwendung benötigt wird.

<html>
<head>
<style type="text/css">
#div1 { background-color: #00ff00; margin: 10px; padding: 10px; }
#div2 { background-color: #0000ff; margin: 10px; padding: 10px; }
</style>
<script type="text/javascript">

function init()
{
  var total = 1;

  var div1 = document.getElementById('div1'),
      div2 = document.getElementById('div2');

  var helper = function(event, id)
  {
      if (event.stopPropagation) event.stopPropagation();
      if (event.preventDefault) event.preventDefault();

      alert('id='+id);
  }

  div1.addEventListener('click', function(event) { helper(event, total); }, false);

  total += 4;

  div2.addEventListener('click', function(event) { helper(event, total); }, false);

}

</script>
</head>

<body onload="init();">

<div id="div1">1</div>
<div id="div2">2</div>

</body>
</html>

Vielen Dank für Ihre Hilfe! :-)

8voto

Matt Punkte 42232

Das Problem ist, dass die Ereignis-Listener und 'total' beide im selben Bereich (init()) existieren.

Die Ereignisfunktionen verweisen immer auf die Gesamtsumme innerhalb des init()-Bereichs, auch wenn sie nach der Deklaration der Ereignisfunktionen geändert wird

Um dies zu umgehen, müssen die Ereignisfunktionen in ihrem eigenen Anwendungsbereich eine "Summe" haben, die sich nicht ändert. Sie können mit einer anonymen Funktion eine weitere Ebene des Anwendungsbereichs hinzufügen

Zum Beispiel:

(function (total) {
    div1.addEventListener('click', function(event) { helper(event, total); }, false);
}(total));

total += 4;

(function (total) {
  div2.addEventListener('click', function(event) { helper(event, total); }, false);
}(total));

Den anonymen Funktionen wird der aktuelle 'total'-Wert von init() als Parameter übergeben. Dadurch wird ein weiterer "total"-Wert in den Bereich der anonymen Funktion gesetzt, so dass es keine Rolle spielt, ob sich der "total"-Wert von init() ändert oder nicht, da die Ereignisfunktion ERST auf den Bereich der anonymen Funktion verweisen wird.

Edit :

Außerdem müssen Sie nach der schließenden Klammer der Hilfsfunktion ein Semikolon setzen, da sich das Skript sonst beschwert, dass "event" undefiniert ist.

var helper = function(event, id)
{
  if (event.stopPropagation) event.stopPropagation();
  if (event.preventDefault) event.preventDefault();

  alert('id='+id);
};

0 Stimmen

Ahh. Total wird also effektiv zu einem Variablenzeiger, ähnlich wie in C++ variable*?

0 Stimmen

Tatsächlich wird es in einen lokalen Bereich kopiert. Wenn es ein Zeiger war, dann würde es sowohl innerhalb als auch außerhalb des Bereichs ändern, die Sie zurück zu Ihrem ursprünglichen Problem bringen würde.

2 Stimmen

Das Beispiel von @Gary Matt ist richtig, hier ein paar Begrifflichkeiten für Sie. Sie hatten Ihr spezielles Problem aufgrund einer so genannten "Schließung" ( jibbering.com/faq/faq_notes/closures.html ), was eine großartige und leistungsstarke Funktion von JavaScript ist. Matt hat Ihnen gezeigt, wie Sie die Closure-Eigenschaft (die, wie Sie gesehen haben, manchmal im Weg steht) mit anonymen Funktionen und einer Technik, die als Currying bekannt ist, umgehen können. Siehe ejohn.org/blog/teilfunktionen-in-javascript y stackoverflow.com/questions/1413916 .

3voto

m4roo Punkte 21

Das ist fast dasselbe, aber ich denke, es wird besser sein:

div1.addEventListener('click', function(t){ return function(event) { helper(event, t); }}(total), false);

anstelle von:

(function (total) {
    div2.addEventListener('click', function(event) { helper(event, total); }, false);
}(total));

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X