Reagowanie na zdarzenie onmousemove poza oknem przeglądarki w IE

W Internet Explorerze 7 body onmousemove lub document.zdarzenia onmousemove wydają się uruchamiać tylko wtedy, gdy mysz znajduje się w oknie przeglądarki, a nie wtedy, gdy jest na zewnątrz. Jednak w Firefoksie Zdarzenie onmousemove jest wywoływane poprawnie, gdy wychodzę poza okno przeglądarki.

Jak skonfigurować Zdarzenie do wywołania poza oknem przeglądarki w IE?

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

Author: Community, 2009-11-06

2 answers

(Uwaga: Ta odpowiedź odnosi się wyłącznie do "standardowej" implementacji przeciągania mousedown -> mousemove -> mouseup. Nie dotyczy HTML5 drag specification ).

Umożliwienie przeciągania poza okno przeglądarki to stary problem, który różne przeglądarki rozwiązały na dwa sposoby.

Z wyjątkiem IE, gdy użytkownik inicjuje operację przeciągania przez mousedown przeglądarki zrobiły coś fajnego (a to wszystko tylko z obserwacji): do obsługi szczególny przypadek ruchów myszy za oknem:

  1. wyzwalacze użytkownika mousedown Zdarzenie wewnątrz document
  2. wyzwalacze użytkownika mousemove Zdarzenie. Zdarzenie wywołane nawet po wywołaniu spoza document (tj. okna)
  3. wywołanie zdarzenia mouseup (wewnątrz lub na zewnątrz document). mousemove zdarzenia wywołane spoza dokumentu już nie wywołują

IE i starsze wersje Firefoksa [aż 2.0.20] nie wykazują takiego zachowania. Przeciąganie za oknem po prostu nie działa1.

Problem dla IE i FF2 polega na tym, czy element jest "do wyboru", czy nie (Zobacz tutaj i tutaj). Jeśli implementacja przeciągania nic nie robi( umożliwiając tym samym zaznaczenie za pomocą myszki), to wspomniana implementacja nie musi uwzględniać ruchów poza oknem; przeglądarka uruchomi się prawidłowo i użytkownik będzie mógł swobodnie przeciągać za oknem. Nieźle.

Jednak pozwalając przeglądarce zdecydować, co zrobić na mousemove, uzyskujesz ten efekt, gdy przeglądarka myśli, że użytkownik próbuje "wybrać" coś (np. element), w przeciwieństwie do przesuwania go, i zaczyna gorączkowo próbować podświetlić element lub tekst w nim, gdy mysz przecina lub wychodzi z elementu podczas przeciągania.

Większość implementacji przeciągania, które widziałem, robi małą sztuczkę, aby przeciągany element był "niewykrywalny", przejmując w ten sposób pełną kontrolę nad mousemove aby symulować przeciąganie:

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

To działa ładnie, ale przerywa przeciąganie za oknem. 2

W każdym razie , aby odpowiedzieć na twoje pytanie, aby IE (wszystkie wersje) umożliwiało przeciąganie poza okno, użyj setCapture (i odwrotnie releaseCapture po zwolnieniu 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 można zobaczyć tutaj .

To jest dokładnie to, co robi Google maps (jak odkryłem od reverse engineering google mapy z powrotem w 2004 roku, kiedy to został po raz pierwszy wydany).


1wydaje mi się, że łamie się tylko podczas inicjowania operacji przeciągania (np. mousedown) na textnode. Węzły elementu / kontenera nie zachowują się tak samo i mogą być przeciągane wewnątrz lub na zewnątrz dokumentu, pod warunkiem, że użytkownik zostanie zablokowany na "pustej" części elementu

2ponownie, dla inicjacji przeciągnij na textnodes.

 70
Author: Crescent Fresh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-04-05 13:21:11

Możesz spojrzeć na kod tutaj, ponieważ wygląda na to, że działa w IE8 i FF3. 5. Jeśli dobrze rozumiesz jego kod. http://www.walterzorn.de/en/dragdrop/dragdrop_e.htm

 2
Author: James Black,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-30 15:49:00