Ich habe vor Jahren über die Positionsfunktion von jQuery UI geschrieben, aber ich dachte gerade daran, wie nützlich der Teil der Kollisionserkennung dieser Funktion ist. Kurz gesagt: Sie können ein Element dort positionieren, wo Sie es haben möchten, aber wenn berechnet wird, dass die Position, an die Sie es verschieben, außerhalb des Bildschirms oder anderweitig nicht sichtbar wäre, passt es die Positionierung an, um dies zu beheben.
Hier ist ein Beispiel von Disqus, wo das Standardverhalten für dieses Benutzer-Popup darin besteht, sich nach oben zu öffnen, aber wenn es vom oberen Bildschirmrand verdeckt würde, öffnet es sich stattdessen nach unten.

Ich habe kürzlich dasselbe bei CodePen gemacht, um sicherzustellen, dass der Einstellungen-Dropdown-Bereich nicht unterhalb des Seitenrands geöffnet wurde, sondern stattdessen nach oben geöffnet wurde.

Immer wenn ein Element auf einer Seite gerichtet geöffnet wird und Sie nicht zu 100 % sicher sind, dass diese Richtung nicht verdeckt wird, ist eine Kollisionserkennung eine gute Idee.
Tooltips sind ein klassisches Beispiel. Sie könnten einen Tooltip so gestalten, dass er oberhalb und rechts von einem Link geöffnet wird.
$("a[data-tooltip]")
.on("mouseenter", function() {
var whichTip = $(this).data("tooltip");
$(".tooltip[data-tooltip=" + whichTip + "]")
.position({
my: "left bottom",
at: "left top",
of: $(this)
})
.show();
});
(PS: Wäre es nicht schön, wenn wir Tooltips mit HTML darin irgendwie ohne JS machen könnten?)

Aber wenn sich dieser Link nahe am oberen Rand der Seite befand, könnte sich das leicht über den Rand hinaus öffnen und ziemlich nutzlos sein.

Es könnte auch gefährlich an einem Rand sein, je nachdem, wie es gestaltet ist.

jQuery UI hat standardmäßig die Kollisionserkennung aktiviert und wird "flips", was bedeutet,
Dreht das Element auf die gegenüberliegende Seite des Ziels und die Kollisionserkennung wird erneut ausgeführt, um zu sehen, ob es passt. Die Seite, die mehr vom Element sichtbar lässt, wird verwendet.
Sie müssen das explizit ausschalten, wenn Sie möchten. Kollision hat auch ein paar andere Werte, darunter fit, das die Position verschiebt, bis das Element auf die Seite/den Bereich passt, oder fitflip, das zuerst dreht und dann nach Bedarf passt.
Das würde so aussehen, mit jQuery UI position
$("a[data-tooltip]")
.on("mouseenter", function() {
var whichTip = $(this).data("tooltip");
$(".tooltip[data-tooltip=" + whichTip + "]")
.position({
my: "left bottom",
at: "left top",
of: $(this),
collision: "flipfit"
})
.show();
});
Wenn sich der Tooltip nun öffnen und vom oberen Rand oder Rand verdeckt würde, wird er gedreht oder verschoben, um zu passen.

Wie funktioniert das? Mathematik!
Ich bin sicher, Sie können sich vorstellen, wie. JavaScript kennt die Abmessungen und die Position aller Elemente und des Viewports selbst. Es kann also eine kleine Überprüfung durchführen wie: Passt ein Element dieser Größe an dieser Position in diesen Bereich?
Wenn Sie jQuery UI nicht verwenden möchten, könnten Sie sicherlich Ihre eigene Lösung entwickeln. Eine Sache, die ich empfehlen würde, wenn Sie dies tun: Fügen Sie dem Element Klassennamen hinzu, wenn es ein Flip oder Fit durchführt. Das fehlt derzeit in jQuery UI, und Sie benötigen möglicherweise diese Klassennamen, um andere Elemente im Tooltip zu beeinflussen. Sagen wir, um sicherzustellen, dass ein Zeigerpfeil an der richtigen Stelle zeigt.
Einfache Demo
Der Container, gegen den die Kollisionserkennung funktioniert, muss nicht der Viewport sein, es kann ein bestimmter Container sein. Das ist es, was hier geschieht, nur um es zu demonstrieren.
Sehen Sie den Pen collision detection von Chris Coyier (@chriscoyier) auf CodePen.
Und das JS, das die Tooltips auch versteckt
$("a[data-tooltip]")
.on("mouseenter", function() {
var whichTip = $(this).data("tooltip");
$(".tooltip[data-tooltip=" + whichTip + "]")
.position({
my: "left bottom",
at: "left top",
of: $(this),
collision: "flip",
within: ".page-wrap"
})
.show();
})
.on("mouseleave", function() {
var whichTip = $(this).data("tooltip");
$(".tooltip[data-tooltip=" + whichTip + "]")
.stop()
.fadeOut(function() {
$(this).removeAttr("style");
});
});
Ist das auf Codepen live? Wenn ja, funktioniert es bei mir nicht. Ich habe meine Fenster häufig auf seltsam kurze Größen eingestellt und kann nicht auf die Menüs zugreifen, daher wäre das erstaunlich.
Wie lange ist es her, seit Sie es versucht haben? Es war eine Weile ein Problem, ist aber jetzt behoben.
Es sollte funktionieren. Hauptsächlich für die Fälle, in denen sich die Editoren im linken oder rechten Modus befinden und die Einstellungen unterhalb des Seitenendes geöffnet würden, es aber oben Platz gibt. Es gibt Grenzen dafür, was Kollisionserkennung leisten kann =). Fühlen Sie sich frei, den Support zu kontaktieren, wenn es eine Stelle gibt, an der Sie denken, dass es funktionieren sollte, es aber nicht tut.
Danke Chris, ich werde den Support kontaktieren.
Wie unterscheidet sich das von einem Hover-Ereignis? In dieser Anwendung scheint es keinen Unterschied zu geben. In 3D CSS sind Kollisionen sinnvoller.
Kollisionserkennung bezieht sich auf Hover insofern, als wenn ein Hover-Ereignis ein Element offenlegt, aber die Position dieses offenbarten Elements versteckt oder abgeschnitten wäre, ist es gut, das (Kollisionserkennung) zu wissen, damit Sie es an eine Stelle verschieben können, an der es nicht versteckt oder abgeschnitten ist.
Es ist immer schön, auf ein weiteres 'Werkzeug für die Werkzeugkiste' aufmerksam gemacht oder daran erinnert zu werden. Danke, Chris.
Was ist, wenn es sich in einem iFrame befindet, der an sich groß genug ist, dass er nicht scrollen muss, aber seine enthaltende Seite klein genug ist, dass ein Element in diesem iFrame teilweise verdeckt werden kann?
Eigentlich ist dieses Ding cool! Aber im Codepen, wenn wir das Fenster vergrößern, öffnet sich das Popup (Informationen) immer auf der unteren Seite dieses kleinen Einstellungsicons!
Ich habe in Firefox getestet!
Versuchen Sie vielleicht, den Cache zu leeren oder so etwas. Hier ist Firefox für mich: http://cl.ly/YUj4
Fühlen Sie sich frei, den Support zu kontaktieren, wenn es eine Stelle gibt, an der Sie denken, dass es funktionieren sollte, es aber nicht tut. Ein Screencast und detaillierte Browserinformationen wären hilfreich.
Ja Chris..! Okay..! (Ich werde es auch mit den neuesten Versionen von Chrome & IE überprüfen!)
Hallo Chris,
Dies ist TJ vom jQuery UI-Team. Danke für den Artikel. Als Information, Sie können die von Ihnen gesuchten CSS-Klassennamen mit der
using-Eigenschaft relativ einfach erhalten. Hier ist ein Beispiel für die Verwendung dieser Eigenschaft zum Styling von Pfeilen: http://jsfiddle.net/tj_vantoll/587n9/.Ich habe letzte Woche gerade meine eigene Lösung für ein paar Popups auf einer Website erstellt. Ich wusste gar nicht, dass JQuery UI diese Fähigkeit hat! Ziemlich cool, wenn man es schnell einrichten und fertig sein will :)
Je mehr ich mir das ansehe, desto mehr wünsche ich mir eine weitere CSS-Regel für solche absolut positionierten Elemente, zum Beispiel
Während das Skalieren dieser Elemente eine weitere feine Funktion in CSS wäre... :-)
Ein anderer Ansatz wäre die Verwendung eines Selektors wie :validate, zum Beispiel
Das wäre eine wirklich schöne Funktion für all die GUI-Entwickler da draußen...
Das ist gut auf Codepen gelungen (und ich sehe, dass Sie auch das andere erledigt haben, danke).