(. Uwaga: ta odpowiedź odnosi się wyłącznie do „standardowego” realizacji wleczonego mousedown -> mousemove -> mouseup
To nie ma zastosowania do HTML5 drag specification).
Umożliwienie przeciągania poza okno przeglądarki to stary problem, który różni przeglądarki rozwiązały na dwa sposoby.
Z wyjątkiem IE, gdy użytkownik inicjuje operację przeciągania za pomocą mousedown
przeglądarek zrobiło coś porządnego (a to wszystko tylko z obserwacji): rodzaj statemachine kopnięć w celu obsługi specjalnego przypadku ruchów myszy poza okno:
- Użytkownik uruchamia
mousedown
wydarzenie wewnątrz document
- użytkownika wyzwala
mousemove
wydarzenie. Zdarzenie nawet gdy wywołany spoza document
(to okno)
- użytkownika wyzwala
mouseup
zdarzenie (wewnątrz lub na zewnątrz document
). mousemove
zdarzenia wywołane spoza dokumentu nie pożarnej
IE i starsze wersje Firefoksa [tak późno, jak 2.0.20] nie wykazują takiego zachowania. Przeciąganie poza okno po prostu nie działa .
Problem IE i FF2 w rzeczywistości polega na tym, czy element jest "możliwy do wybrania", czy nie (patrz: here i here). Jeśli implementacja przeciągania nic nie robi (co pozwala na wybór przez mysz), to wspomniana implementacja nie musi uwzględniać ruchów poza oknem; przeglądarka uruchomi się poprawnie i odpali mousemove
, a użytkownik będzie mógł swobodnie przeciągać się poza okno. Miły.
Jednakże, pozwalając przeglądarce zdecydować, co zrobić na mousemove, uzyskuje się ten efekt, gdy przeglądarka myśli, że użytkownik próbuje "wybrać" coś (np. Element), a nie poruszać nim, i przystępuje do gorączkowej próby podświetlić element lub tekst, gdy myszka wkracza lub wychodzi z elementu podczas przeciągania.
Większość implementacji drag widziałem zrobić małą sztuczkę, aby element przeciągany „Nie można wybrać”, tym samym biorąc pełną kontrolę mousemove
symulować przeciąganie:
elementToDrag.unselectable = "on";
elementToDrag.onselectstart = function(){return false};
elementToDrag.style.userSelect = "none"; // w3c standard
elementToDrag.style.MozUserSelect = "none"; // Firefox
Działa to dobrze, ale przerwy przeciągając za oknem.
Zresztą, aby odpowiedzieć na to pytanie, aby uzyskać IE (wszystkie wersje), aby umożliwić przeciągnięcie za oknem, użyj setCapture
(i odwrotnie releaseCapture
po zwolnieniu przycisku myszy).
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Simple drag demo</title>
<style>
#dragme {
position:absolute;
cursor:move;
background:#eee;
border:1px solid #333;
padding:10px;
}
</style>
<script>
function makeDraggable(element) {
/* Simple drag implementation */
element.onmousedown = function(event) {
document.onmousemove = function(event) {
event = event || window.event;
element.style.left = event.clientX + 'px';
element.style.top = event.clientY + 'px';
};
document.onmouseup = function() {
document.onmousemove = null;
if(element.releaseCapture) { element.releaseCapture(); }
};
if(element.setCapture) { element.setCapture(); }
};
/* These 3 lines are helpful for the browser to not accidentally
* think the user is trying to "text select" the draggable object
* when drag initiation happens on text nodes.
* Unfortunately they also break draggability outside the window.
*/
element.unselectable = "on";
element.onselectstart = function(){return false};
element.style.userSelect = element.style.MozUserSelect = "none";
}
</script>
</head>
<body onload="makeDraggable(document.getElementById('dragme'))">
<div id="dragme">Drag me (outside window)</div>
</body>
</html>
Demo can be seen here.
To jest dokładnie to, co robią mapy Google (jak odkryłem odkąd inżynieria odwrotna google odwzorowuje w 2004 r., Kiedy została wydana po raz pierwszy).
wierzę, że faktycznie tylko łamie podczas rozpoczynania operacji przeciągania (tj mousedown
) na textnode. Element/węzły pojemnik nie wykazuje takie samo zachowanie i można przesuwać wewnątrz lub na zewnątrz w dokumencie, pod warunkiem, użytkownik moused dół „pustym” część elementu
Ponownie, inicjacji przeciągnij textnodes.
genialna odpowiedź! –
To zaoszczędziło mi tyle frustracji! IE to taki, który potrzebuje Capture i ma go. Pozostałe poprawnie wykrywają mouseup poza dokumentem. –
Hi Crecent Fresh, mam jedną skrzynkę, gdzie zawsze, gdy pojawi się 'mouseup' po' mousedown', powinien pojawić się alert. Tak więc, po 'mousedown' na dokumencie, jeśli użytkownik przeciągnie mysz z okna myszką wciąż w dół, i zwalnia ją za oknem, alarm powinien wyskoczyć. Jak mam to zrobić? Nie bardzo rozumiem twój kod, ponieważ dotyczy on takich rzeczy, jak wybór i przeciąganie ... – SexyBeast