2009-08-25 10 views
1

Diese Frage ist ähnlich wie my last question about "too much recursion" errors in jQuery, aber beteiligt Live-Handler. Ich habe ein Element in einem anderen. Beide haben benutzerdefinierte Ereignishandler mit dem gleichen Namen. Das äußere Element hat einen traditionellen Handler und das innere Element hat einen Live-Handler. Wenn ich versuche, das Ereignis auf dem äußeren Element auszulösen, hält mein Browser eine Weile an, dann wird ein Fehler angezeigt, der "zu viel Rekursion" sagt."zu viel Rekursion" Fehler mit Live-Handler in jQuery 1.3.2

Ich las auf live handler documentation page, dass ich Blasenbildung eines Live-Handlers verhindern kann, indem Sie innerhalb der Handler-Funktion false zurückgeben. Allerdings habe ich das versucht und es scheint keinen Unterschied zu machen. Wie auch immer, die äußere Funktion scheint irgendwie oft aufgerufen zu werden, wenn ich versuche, sie nur einmal zu nennen.

Wie kann ich das beheben? Ist es möglich, Handler mit dem gleichen Namen zu haben, oder muss ich mir andere Namen einfallen lassen? Sie können das Problem testen diesen Code verwenden:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 
<html><head> 
<title>live event handler test</title> 
</head> 
<body> 
<div id="outer"> 
    <div id="inner"> 
    </div> 
</div> 
<script type="text/javascript" src="jquery-1.3.2.min.js"></script> 
<script type="text/javascript"> 
$("#outer").bind("test", function() { 
    $("#inner").trigger("test"); 
}); 

$("#inner").live("test", function() { 
    return false; 
}); 

$(function() { 
    $("#outer").trigger("test"); 
}); 
</script> 
</body></html> 
+0

Schöner kompletter Testfall. –

Antwort

1

Blick auf #outer ‚s Rückruf:

$("#outer").bind("test", function() { 
    $("#inner").trigger("test"); 
}); 

Sie "test" auf #inner auslösen, aber #inner ein Kind von #outer ist, so dass die Veranstaltung "sprudelt" zu #outer und der gesamte Prozess wiederholt sich (bis es explodiert).

bearbeiten: als @Seth weist darauf hin, wenn Sie live() verwenden beide auf #outer und #inner es funktioniert. Das liegt daran, dass "return false;" in diesem Fall wie event.stopImmediatePropagation() funktioniert. Ebenso, wenn Sie bind() auf beiden verwenden, funktioniert es auch. Das liegt daran, dass "return false;" in diesem Fall wie event.stopPropagation() funktioniert.

Sie mischen jedoch beide und verwenden bind auf #outer und live auf #inner. Net-Effekt ist, dass das Auslösen Ihres Ereignisses, wie ich darauf hinwies nie ausführen wird live Handler (d. H. return false wird nie ausgeführt), weil it is bound to the document, und das Ereignis nie eine Chance bekommen, um die document wegen der Stapelüberlauf Blase.

Edit 2:

Gibt es eine Möglichkeit, die sprudelnden auf der inneren Ereignis zu verhindern? (unter Verwendung von live()?)

Nein. Siehe jquery Event.stopPropagation() seems not to work eine bessere Erklärung.

+0

Warum sprudelt das Ereignis auf #inner bis #outer?Soll das nicht durch die "return false" -Anweisung verhindert werden? –

+0

Warum gibt es einen Stapelüberlauf? Wenn der Live-Handler niemals ausgeführt wird, sehe ich nicht, warum die äußere Funktion mehr als einmal aufgerufen wird. –

+0

@ mikez302: 'Trigger' Blasen. So einfach ist das. Entferne 'live' und das Problem besteht immer noch. 'live' hat damit nichts zu tun. Der Wortlaut meines letzten Absatzes verwirrte die Frage, die ich denke. Das Problem ist immer noch das, was ich im ersten Absatz gesagt habe. –

0

Es scheint, wie die Kombination von Live-und bindet für ein benutzerdefiniertes Ereignis einen Fehler in er hat? Nicht ganz sicher, was eigentlich vor sich geht. Wenn Sie nur Live verwenden es funktioniert:

$("#outer").live("test", function() { 
    console.log("outer"); 
    $("#inner").trigger("test"); 
}); 

$("#inner").live("test", function() { 
    console.log("inner"); 
    return false; 
}); 

$(function() { 
    $("#outer").trigger("test"); 
}); 

nicht in die Quelle zu viel gegraben haben, aber es scheint, wie bind den Rückgabewert der Funktion ignoriert.

+0

Wirklich? Ich habe versucht, die "Test" Namen zu "klicken" und ich bekomme den genau gleichen Fehler. –

+0

Ja, ich habe mich geirrt. Meine Antwort wurde aktualisiert. – seth

Verwandte Themen