2015-06-24 11 views
12

Ich habe eine Geige erstellt, um zu versuchen, ein Problem zu debuggen, das ich habe, wo, sobald ich HTML-Elemente mit jQuery neu anordnen, schweben Ereignisse auf diesen Elementen nicht mehr arbeiten.Ändern Sie die Element-ID, aber jQuery löst weiterhin das Ereignis aus, das die alte ID aufruft. Warum funktioniert das?

Allerdings stieß ich auf diese interessante Situation hier: http://jsfiddle.net/4yv1trj4/

Ich habe eine Haupt div die Farbe wechselt, wenn ich den Mauszeiger über sie.

$("#block").hover(function() { 
    $(this).css("backgroundColor", "red"); 
}, function() { 
    $(this).css("backgroundColor", "#888");   
}); 

Wenn Sie auf die Schaltfläche klicken, die wichtigsten div ‚s ID Änderungen block2:

$("#block").attr("id","block2"); 

aber $("#block").hover() feuert immer noch, wenn ich über #block2 schweben. Außerdem funktionieren alle Hover-Aufrufe unter #block2 nicht. Gibt es ein grundlegendes Prinzip, wie jQuery funktioniert, das dies erklären würde?

Antwort

18

Wenn Sie dies tun:

$("#block").hover(function() { 
    $(this).css("backgroundColor", "red"); 
}, function() { 
    $(this).css("backgroundColor", "#888");   
}); 

Sie jQuery doch sagen, mit dem block ID für das Element zu schauen und das Hover-Ereignis, um es zu binden. Sobald dies erledigt ist, bleibt das Ereignis an dieses Element gebunden, egal was mit seiner ID danach passiert.

Das heißt, es sei denn, Sie haben einen Code, unbinds es natürlich.

+0

Danke, das hilft mir, es ein wenig zu verstehen. http://jsfiddle.net/4yv1trj4/5/ Ich aktualisierte die jsfiddle, um zu lösen und zu re-binden, aber Code sieht hässlich wie Hölle aus und ich kann nicht helfen zu glauben, dass es viel bessere Möglichkeiten geben könnte, dies zu tun. Denkst du, dass Technophobias Antwort eine bessere Option wäre, meinen Code zu verkleinern? – mcheah

+0

Ich mag Technophobie Workaround, obwohl ich es nicht für Ihren Anwendungsfall aufgrund der Probleme von Canon (http://stackoverflow.com/questions/31032004/change-element-id-but-jquery-still-fires) empfehlen würde -event-calling-alt-id-warum-tut-das-wor/31032094 # comment50091306_31032395). Ich denke, deine Lösung war nicht so schlecht. – lucasnadalutti

+0

Offensichtlich gibt es einen Handel, mit dem Sie zu kämpfen haben - ich persönlich habe '.on()' Container Bindungen in unzähligen Projekten mit minimalen Auswirkungen auf die Leistung verwendet. – technophobia

2

Wenn Sie die jQuery Hover Zuhörer entfernen und eine CSS-Hover hinzufügen, funktioniert es, wie Sie wollen:

#block:hover { 
    background-color:red; 
    width:300px; 
    height:300px; 
} 
+0

Dies. JQuery für solch eine Aufgabe zu verwenden ist unnötig – rev

9

Als Erweiterung lucasnadalutti Antwort: Es erwähnenswert ist, dass Sie die Bindung an den Behälter hinzufügen und ergeben das Ergebnis Sie erwarten:

Beispiel:

$("body").on("mouseenter", "#block", function() { 
    $(this).css("backgroundColor", "red"); 
}).on('mouseleave', "#block", function() { 
    $(this).css("backgroundColor", "#888"); 
}); 

Beachten Sie die Bindung auf der body, nicht das eigentliche Element. Ein Trick, um in deiner Gesäßtasche zu bleiben.

Demo:jsFiddle


Update:

Aus den Kommentaren, es ist klar, eine Warnung erforderlich ist - Sie zum nächsten Element auf der Seite binden sollte. body wurde hier als einfaches Beispiel verwendet.

Obwohl ich denke, dass diese Lösung Ihnen elegant passen würde, sollten Sie Should all jquery events be bound to $(document)? lesen, bevor Sie beginnen, diese Macht zu missbrauchen.

+0

interessant, ich hatte nie gewusst, dass dies eine Option war. Wenn ich alle meine click() - und hover() -Ereignisse durch diese ersetze, würde ich daran denken, dass dies eine schlechte Übung wäre, wenn man bedenkt, dass ich viele Bindungen und Entbindungen in meinen Code einfügen müsste, wenn ich das tun würde Route? Vielen Dank! – mcheah

+0

@Matt ja, es gibt Probleme. Es bedeutet im Wesentlichen, dass Ihre Ereignisse den ganzen Weg durch das DOM zu "Körper" sprudeln müssen, bevor sie behandelt werden können. Wenn irgendetwas auf dem Weg aufhört zu verbreiten, sind Sie in Schwierigkeiten. Im Allgemeinen ist dieses Muster für dynamischen Inhalt reserviert oder um das Anhängen einer großen Anzahl von Handlern zu vermeiden, d. H. Eines für jedes Listenelement in einer Liste. Unabhängig davon, wenn Sie [Ereignisdelegierung] (http://learn.jquery.com/events/event-delegation/) verwenden, möchten Sie immer den nächsten zuverlässigen Vorfahren auswählen, anstatt einfach "body" zu verwenden. – canon

+0

Wenn Sie dies auf einer kleinen Seite testen, werden diese Ergebnisse wahrscheinlich gut sein; Wenn die Seite jedoch anwächst, wird jedes Ereignis, das an Ihr body-Tag angehängt wird (oder an das, was Sie mit der Empfehlung von canon anhängen), immer mehr Ressourcen benötigen. Also ... für zukünftige Erweiterungen, können Sie die Empfehlung von Lucasnadalutti verwenden, die Tags direkt zu verwenden und sie nach Bedarf zu lösen (es sei denn natürlich, Sie wissen, dass der Inhalt des relevanten Tags relativ klein bleibt) – technosaurus

2

$("#block") sucht nach einem bestimmten DOM-Objekt. .hover() bindet ein Hover-Ereignis an dieses DOM-Objekt. $("#block").attr("id","block2"); wird ein Attribut (ID) dieses DOM-Objekts ändern, aber das Hover-Ereignis ist immer noch daran gebunden.