Die Anwendung ist eine Webkarte (OpenLayers 2), auf der man Dialogfelder öffnen kann, indem man auf bestimmte Funktionen klickt. Dialogfelder werden mit jQuery-ui behandelt.Ereignis-Listener-Konflikt zwischen jQuery und OpenLayers
Der Fehler: Wenn der Benutzer bei der Größenänderung eines Dialogfelds den Cursor zu schnell zieht, ist die Größe des Dialogfelds zu groß. Normalerweise würde das ziemlich ruckartige Bewegungen erfordern, aber aufgrund der Tatsache, wie gepackt diese Anwendung geworden ist, denke ich, dass es ein bisschen langsamer ist.
Es gibt jedoch einen Konflikt zwischen jQuery und OpenLayers. Wenn der Cursor den Div-Wert an anderer Stelle übertrifft, ist er in Ordnung, aber wenn er über der Map ist, wird die Größenanpassung gestoppt (auch wenn Sie den Mauszeiger nicht bewegen), wird die Größe des Mauszeigers geändert Bewegung).
Dies bedeutet, um den Dialog zu erweitern, müssen Sie den Cursor absichtlich sanft und nicht zu schnell bewegen, sonst bricht es, was offensichtlich zu problematisch für die Benutzererfahrung ist.
Richten Sie eine sehr einfache jsfiddle (http://jsfiddle.net/a6uu5vav/) einfach versuchen, den Dialog schnell ziehen oder die Größe ändern. Kann je nach Computer/Browser variieren, funktioniert aber (funktioniert nicht) für mich in Chrome.
Der Grund: jQuery-ui scheint den Ereignis-Listener mit Bezug zu ziehen/der Größe an document
zu befestigen, so sollte die Funktionalität unabhängig von outpacing div Maus arbeiten. OpenLayers setzt aber auch jede Menge Event-Listener auf alles, was es erzeugt. Es verwendet event.stopPropagation()
, so dass nur die Listener auf dem Zielelement jedoch benachrichtigt werden.
Wenn also der Cursor über der OpenLayers-Map liegt, werden die Ereignis-Listener des Ziels ausgelöst, das Ereignis wird jedoch nicht an die Größenlistener weitergeleitet. Während das Auskommentieren von stopPropagation()
es technisch löst, wegen der Verschachtelung von OpenLayers und wie es Event-Listener für alles gibt, macht es das ziemlich langsam, einfach über die Map zu schweben.
Ich habe versucht, den Dialog Modal zu testen, dass es in der Tat widersprüchliche Event Listener ist. Modal behebt das Problem der Größenänderung, aber wir möchten nicht, dass es modal ist. Möglicherweise ist eine "hacky" -Lösung ein unsichtbares Modal und erscheint/verschwindet mit den mousedown/up-Ereignissen, die den Ziehvorgang starten/beenden.
My Fix Versuch: Ich ging in jQuery-ui (in der ui.mouse
Definition), um die Ereignis-Listener zu modifizieren, auf Capture (statt Blase) zu feuern, die, da sie zu dem Dokument hinzugefügt werden, wird dann garantiert werden, Feuer. Da jQuery.bind()
das nicht unterstützt, habe ich auf Old-School-addEventListener()
umgeschaltet, aus Konsistenz habe ich auch alle verwandten unbind()
zu removeEventListener()
geändert.
Jetzt ist die Sache, wenn ich nur das getan habe, aber immer noch onCapture
param für addEventListener()
auf falsch gesetzt, es funktioniert genau wie es vorher getan hat - wie gewohnt mit der Größenanpassung Fehler. Wenn ich den Parameter onCapture
für den MouseMove-Listener auf true ändere (spielt keine Rolle, wenn ich mouseup auf true/false setze), ist das Problem der Größenänderung technisch zwar behoben, aber jetzt werden andere Dinge wackelig.
Es schleppt/Größenänderungen gut, aber auf MouseUp, die Ereignislistener scheinen nicht entfernt werden (so bewegt sich Maus noch schleppt oder ändert die Größe des Dialogs), auch div verschiebt sich ohne Grund. _mouseUp()
wird aufgerufen und die Ereignis-Listener zumindest in diesen Zeilen entfernt, ich weiß, es ist kein Callback-Referenz-Problem, das ich dafür getestet habe. Ich denke, sie werden richtig entfernt, aber irgendwie wieder eingefügt.Scheint, dass etwas in jQuery auf Mouse-Up feuert, das zuerst gehen muss und die Reihenfolge irgendwie neu anordnen muss, selbst wenn dieses Bit es komplett ablegt.
Dies könnte ein verlierendes Spiel sein (d. H. Zeitverlust insgesamt relativ zum Bug), um jQuery-ui dafür zu "patchen", aber ich frage mich, ob es noch andere Ideen gibt, wie man das versucht.
Können Sie näher darauf eingehen? Ich versuche zum Beispiel in '_mouseDestroy' die Zeile' this.document.unbind ("mousemove." + This.widgetName, this._mouseMoveDelegate) 'mit' this.document.get (0) .removeEventListener zu ersetzen ('mousemove.' + this.widgetName, this._mouseMoveDelegate, true) '. Wenn Sie jedoch alle Zeilen, die Sie erwähnt haben, mit dieser Strategie geändert haben, wurde die Größenänderungsfunktionalität auf der Seite praktisch aufgehoben. Mache ich etwas anderes als du? –
Ok, verstanden. Ich musste den jQuery Namespace von den Ereignisnamen entfernen, und dann funktionierte es. Anstatt '.... removeEventListener ('mousemove.' + This.widgetName, ....)' habe ich '.... removeEventListener ('mousemove', .....)'. Außerdem gibt es eine Zeile in meiner Version von jQuery UI, in '_mouseDestroy', also' this.element.unbind ("." + This.widgetName); '. Ich habe das nicht angefasst. Nur diejenigen, die Ereignisse an das 'Dokument' binden und von diesen entfernen. Danke @wowohweeawah für deine ausführliche Antwort. Das hat mein Problem behoben. –