2012-06-13 14 views
9

Ich verwende hammer.js und es scheint, dass ich event.stopPropagation() nicht mit Tap-Ereignis funktioniert.stopPropagation() mit Tippen Ereignis

Wenn ich auf das untergeordnete Element klicke, wird das zugeordnete Ereignis ausgelöst, aber auch das Ereignis des übergeordneten Elements wird ausgelöst, und das möchte ich nicht. Hier

$('#parent').hammer().bind('tap', function(e) { 
    $(this).css('background', 'red'); 
});​​​​​​​​ 

$('#child').hammer().bind('tap', function(e) { 
    e.stopPropagation(); 
    $(this).css('background', 'blue'); 
}); 

ist ein Beispiel: http://jsfiddle.net/Mt9gV/

ich auch versucht, mit jGestures und das Problem scheint das gleiche zu sein. Wie kann ich dieses Ergebnis mit einer dieser Bibliotheken erreichen? (oder ein anderes, wenn es benötigt wird)

+0

Ich denke, dass es etwas mit der Tatsache zu tun hat, dass Sie die "Hammer" Sachen auf den Eltern- und Kind-Elementen eingerichtet haben. Ich bin mir aber nicht 100% sicher. – Pointy

+0

Wenn ich keinen Hammer auf beide Elemente anwende, funktioniert das Tap-Event leider nicht. – TimPetricola

Antwort

8

Wie in einem anderen Kommentar erwähnt, würde man erwarten, wie Sie getan haben, dass event.stopPropagation() Aufruf wäre alles, was Um das Ereignis vom Bubbling bis zum Parent zu stoppen.

Details: Allerdings ist dies in Hammer.js nicht so. Hammer erstellt für jedes Element, auf dem Sie $(el).hammer() aufrufen, eine neue Gestenstatusmaschine. Wenn also ein Berührungsereignis vom Browser auf das Kind ausgelöst wird, wird es zuerst von der Logik für Kind und dann wieder von der Logik des Elternteils verarbeitet. Als solches um zu verhindern, dass die Eltern das Ereignis erreichen, müssen Sie verhindern, dass die Hammermaschine des Elternteils das ursprüngliche Berührungsereignis erhält. Im Allgemeinen wird durch das Aufrufen von event.stopPropagation() auch die Weitergabe des ursprünglichen Ereignisses gestoppt. Das Ereignis tap von hammer.js wird jedoch auf touchend ausgelöst, aber originalEvent ist das zwischengespeicherte Ereignis touchstart. Daher hat das Stoppen der Propagierung des ursprünglichen Ereignisses keine Auswirkungen, da sich das Ereignis touchstart schon seit langem durch das DOM aufbaut.

Lösung? Ich glaube, das ist ein Bug in Hammer - reichen Sie eine Pull-Anfrage, die die originalEvent im Tap-Ereignis korrigiert. Wie andere vorgeschlagen haben, könnten Sie das Ziel des Ereignisses überprüfen, aber das ist immer das Elternelement - ein weiterer Fehler meiner Meinung nach. Überprüfen Sie stattdessen die event.originalEvent.target. Hier ist ein JS fiddle mit dieser mittelmäßigen Lösung implementiert: http://jsfiddle.net/HHRHR/

+5

Hinweis: Meine Antwort auf diese Frage ist veraltet - hammer.js wurde seit der Veröffentlichung erheblich geändert. – rharper

+0

Wir verwenden Code, der fast identisch mit TimPetricolas Original-Snippet ist. Ich kann bestätigen, dass es mit Hammer.JS - v1.0.5 - 2013-04-07 wie erwartet funktioniert. Sieht so aus, als hätte Hammer.js dieses Problem ernst genommen und behoben. – Douwe

0

Wenn Sie dies nicht zur Arbeit bekommen .. rufen Sie einfach eine andere Methode auf den Hahn nach der Überprüfung der Notwendigkeit (arguments.callee ist, wo ich in einem solchen Fall starten würde), würde dies haben die zusätzlichen Vorteile der Vermietung andere Benutzer auch auf die Schaltfläche Haken ...

function myFn(a) { if(a) $(this).css('background', 'red'); else $(this).css('background', 'blue');}

$('#parent').hammer().bind('tap', function(e) { 
    //Check arguments.callee or other data in event and call myFn 
});​​​​​​​​ 

$('#children').hammer().bind('tap', function(e) { 
    //Same here 
}); 
+3

Ich verstehe diese Wörter nicht in dieser Reihenfolge ... –

+2

'arguments.callee' ist [jetzt veraltet] (https://developer.mozilla.org/de/JavaScript/Reference/Functions_and_function_scope/arguments/callee) –

+0

I Ich würde mir vorstellen, dass das nur im Strengen Modus ist ... https://developer.mozilla.org/en/JavaScript/Reference/Functions_and_function_scope/arguments/callee und ich würde mich nicht von solch einer kleinen Sache davon abhalten lassen, die Aufgabe zu erledigen. .. verwenden Sie dies und gehen Sie zurück zum Problem, sobald Sie fertig sind. – Jay

0

Sie könnten versuchen, e.currentTarget Kontrolle (oder ist es e.target?) innerhalb des übergeordneten Handler, um herauszufinden, welches Element abgehört wurde ; Wenn es sich um das untergeordnete Element handelt, kehren Sie einfach sofort zurück, andernfalls fahren Sie mit der Funktion fort.

+0

Schöne Idee, aber es gibt das Elternelement zurück, selbst wenn ich auf das Kind klicke. – TimPetricola

+0

Hmmm. Ich habe den Verdacht, dass Hammer tatsächlich an das "Fenster" -Objekt bindet, um all seine Berechnungen durchzuführen, die globalen X/Y-Koordinaten eines Berührungsereignisses auszuarbeiten und dann zu bestimmen, welches Element davon angeklickt wurde. In diesem Fall hat stopPropagation keine Auswirkungen. Aber ich rate nur von einem kurzen Blick auf die [Hammer.js Quelle] (https://github.com/EightMedia/hammer.js/blob/master/hammer.js)! –

3

Da ich diese Arbeit nicht bekommen konnte, habe ich eine Variable verwendet, um zu wissen, ob das Kind-Ereignis bereits ausgelöst wurde. Es funktioniert ganz gut mit jGestures (Ich habe nicht mit hammer.js versucht)

var childTriggered = false; 

$('#child').bind('tapone', function(e) { 
    $(this).css('background', 'red'); 
    childTriggered = true; 
}); 

$('#parent').bind('tapone', function(e) { 
    if(childTriggered) { 
     childTriggered = false; 
     return;     
    } 
    $(this).css('background', 'blue'); 
}); 

+1

Ich kann bestätigen, dass diese Logik auch mit hammer.js funktioniert. –

3

Ich hatte ähnliche Probleme mit den Touch-Events.

I gelöst durch

return false; 

verwendet, welche die gleiche ist wie der Aufruf e.preventDefault(); e.stopPropagation();

Verwandte Themen