2009-11-06 15 views
25

W programie Internet Explorer 7 ciało onmousemove lub document.onmousemove wydarzenia wydają się tylko do ognia, gdy wskaźnik myszy znajduje się wewnątrz okna przeglądarki, a nie kiedy jest na zewnątrz. Jednak w Firefoksie zdarzenie onmousemove jest wywoływane poprawnie po wyjściu poza okno przeglądarki.Odpowiadając na onmousemove imprezy poza oknem przeglądarki IE

Jak mogę skonfigurować wydarzenie, które będzie wywoływane poza oknem przeglądarki w IE?

Google Maps robi to w IE. Jeśli przytrzymasz przycisk myszy i przesuniesz mysz poza okno przeglądarki, zobaczysz, że mapa nadal się porusza.

Odpowiedz

62

(. 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:

  1. Użytkownik uruchamia mousedown wydarzenie wewnątrz document
  2. użytkownika wyzwala mousemove wydarzenie. Zdarzenie nawet gdy wywołany spoza document (to okno)
  3. 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.

+0

genialna odpowiedź! –

+0

To zaoszczędziło mi tyle frustracji! IE to taki, który potrzebuje Capture i ma go. Pozostałe poprawnie wykrywają mouseup poza dokumentem. –

+0

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

2

Możesz spojrzeć na kod tutaj, ponieważ wydaje się działać w IE8 i FF3.5. Jeśli potrafisz dobrze zrozumieć jego kod. http://www.walterzorn.de/en/dragdrop/dragdrop_e.htm

+1

Dzięki. To jest dość kodatyczny kod, ale wydaje się, że on też używa document.onmousemove, zastanawiam się, jaki jest sekret? –

+0

Nie wiem, nie zbadałem zbyt wiele kodu, ale możesz chcieć użyć Firebug na Firefoksie lub zestawu narzędzi Web Developer na IE, aby zobaczyć, co się dzieje, gdy poruszasz myszą poza przeglądarką. –

+0

Dzięki. Jak będę obserwować, co dzieje się w Firebug lub w pakiecie narzędziowym Web Developer na IE, gdy poruszam myszą? Rozglądałem się za nimi, ale nie widziałem żadnego sposobu na oglądanie wydarzeń. –

Powiązane problemy