2009-11-06 16 views
25

In Internet Explorer 7 corpo onmousemove o document.onmousemove eventi sembrano solo al fuoco mentre il mouse si trova all'interno della finestra del browser, non quando è al di fuori. Tuttavia in Firefox l'evento onmousemove viene chiamato correttamente quando mi muovo al di fuori della finestra del browser.Rispondendo alla manifestazione onMouseMove al di fuori della finestra del browser in IE

Come è possibile impostare un evento da chiamare all'esterno della finestra del browser in IE?

Google Maps fa questo in IE. Se si tiene premuto il pulsante del mouse e si sposta il mouse fuori dalla finestra del browser, è possibile vedere che la mappa si muove ancora.

risposta

62

(Nota:. Questa risposta si riferisce esclusivamente all'esecuzione trascinare "standard" di mousedown -> mousemove -> mouseup non è applicabile alla HTML5 drag specification).

Permettere il trascinamento fuori dalla finestra del browser è un vecchio problema che i diversi browser hanno risolto in due modi.

Con l'eccezione di IE, quando un utente avvia un'operazione di trascinamento tramite mousedown i browser hanno fatto qualcosa di pulito (e questo è tutto solo dall'osservazione): una sorta di statemachine calci per gestire il caso particolare di movimenti del mouse al di fuori del finestra:

  1. innesca utente mousedown evento all'interno della document
  2. utente attiva mousemove evento. generato l'evento anche quando innescato da fuori document (vale a dire la finestra)
  3. utente attiva mouseup evento (all'interno o all'esterno della document). mousemove eventi innescati da fuori documento non è più il fuoco

IE e le vecchie versioni di Firefox [il più tardi 2.0.20] non presentano questo comportamento. Il trascinamento fuori dalla finestra non funziona semplicemente .

Il problema per IE e FF2 consiste in realtà in un elemento "selezionabile" o non (vedere here e here). Se un'implementazione di trascinamento non fa nulla (consentendo quindi la selezione con il mouse), allora detta implementazione non deve tenere conto dei movimenti fuori dalla finestra; il browser andrà avanti e sparerà correttamente mousemove e l'utente può trascinarsi liberamente fuori dalla finestra. Bello.

Tuttavia, lasciando che il browser decida cosa fare su mousemove si ottiene questo effetto in cui il browser pensa che l'utente stia cercando di "selezionare" qualcosa (ad esempio l'elemento), invece di spostarlo, e procede freneticamente a provare evidenzia l'elemento o il testo in esso mentre il mouse entra o esce dall'elemento durante il trascinamento.

maggior parte delle implementazioni di trascinamento che ho visto fare un piccolo trucco per rendere l'elemento trascinati "selezionabile", assumendo così il controllo completo di mousemove per simulare il trascinamento:

elementToDrag.unselectable = "on"; 
elementToDrag.onselectstart = function(){return false}; 
elementToDrag.style.userSelect = "none"; // w3c standard 
elementToDrag.style.MozUserSelect = "none"; // Firefox 

Questo funziona bene, ma pause trascinamento fuori dalla finestra.

Comunque, per rispondere alla tua domanda, per ottenere IE (tutte le versioni) per consentire il trascinamento di fuori della finestra, utilizzare setCapture (e inversamente releaseCapture quando il mouse viene rilasciato).

<!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.

Questo è esattamente ciò che fa Google maps (come ho scoperto dal reverse engineering google maps nel 2004 quando è stato rilasciato per la prima volta).


ritengo realtà solo rompe quando si inizia un'operazione di trascinamento (cioè mousedown) su un TextNode. Elemento/nodi container non presentano lo stesso comportamento e possono essere spostate all'interno o all'esterno del documento, a condizione che l'utente posizionato il mouse giù su una porzione "vuoto" dell'elemento

Ancora, per iniziazioni trascinate sul textnodes.

+0

geniale risposta! –

+0

Questo mi ha salvato così tanta frustrazione! IE è quello che ha bisogno di Capture e ce l'ha. Gli altri rilevano correttamente il mouse fuori dal documento. –

+0

Hi Crecent Fresh, ho un caso, in cui ogni volta che si verifica un 'mouseup' dopo un' mousedown', dovrebbe apparire un avviso. Quindi, dopo 'mousedown' sul documento, se l'utente trascina il mouse fuori dalla finestra con il mouse ancora in basso e lo rilascia fuori dalla finestra, l'avviso dovrebbe apparire. Come lo faccio? Non ho capito molto il tuo codice, dal momento che comporta cose come selezione e trascinamento ... – SexyBeast

2

Qui puoi vedere il codice, poiché sembra funzionare in IE8 e FF3.5. Se riesci a capire bene il suo codice. http://www.walterzorn.de/en/dragdrop/dragdrop_e.htm

+1

Grazie. È un bel codice criptico, ma sembra che stia usando anche il document.onmousemove, mi chiedo quale sia il segreto? –

+0

Non so, non ho esaminato troppo il codice, ma potresti voler utilizzare Firebug su Firefox o il toolkit per gli sviluppatori Web su IE per vedere cosa succede mentre muovi il mouse fuori dal browser. –

+0

Grazie. Come guardo cosa succede in Firebug o nel toolkit per gli sviluppatori Web su IE mentre sposto il mouse? Ho guardato dappertutto entrambi, ma non vedo alcun modo di guardare gli eventi. –

Problemi correlati