2011-12-23 20 views
21

Po przeciągnięciu elementu nad innym div, w którym mam zdarzenie mouseover, zdarzenie nie jest wyzwalane. Działa to jednak, gdy najecham na niego bez przeciągania.Sposób uruchamiania zdarzenia myszy podczas przeciągania

Czy istnieje sposób wykrywania zdarzeń najechania na element, jeśli przeciągnę inny nad nim?

+0

Czy używasz interfejsu jQuery? – Purag

+0

Nie, używam niestandardowego utworzonego przeciągnięcia – user969724

+0

Pomoże to zobaczyć ten kod. Albo umieść to w pytaniu, albo wklej je w [jsfiddle] (http://jsfiddle.net). – Purag

Odpowiedz

13

Oto przykład użycia rozwiązania współrzędnych XY.

Working example on jsfiddle

Przykładem może być ulepszona, ale jest dobry punkt wyjścia.

Po prostu śledzi położenie myszy i sprawdza, czy znajdują się wewnątrz obwiedni zrzucanych obiektów. Dlatego jeśli zdarzenie mouseup jest uruchamiane na którymkolwiek z nich, przeciągnięty obiekt jest upuszczany.

Możesz także użyć współrzędnych obiektu, który przeciągasz, aby wykryć, czy znajduje się on na polu, które można zrzucić, ale wymaga nieco więcej kodu do znajdowania obwiedni prostokąta i wystarczy mi mysz.

Kod używa jQuery, ale nie ma jQueryUI. Testowałem w przeglądarce Chrome, Firefox i Opera, ale nie w IE :)

Dodaję tutaj także kod, jeśli jsfiddle nie jest dostępny.

HTML

<p>Drag orange boxes to grey ones</p> 
<div class="droppable"></div> 
<div class="droppable"></div> 
<div class="droppable"></div> 
<div class="droppable"></div> 

<div class="draggable"></div> 
<div class="draggable"></div> 
<div class="draggable"></div> 

CSS

.droppable { 
    width:50px; 
    height:50px; 
    float: left; 
    background-color: #DDD; 
    margin: 5px; 
} 

.draggable { 
    width:40px; 
    height:40px; 
    float: right; 
    background-color: #FC0; 
    margin: 5px; 
    cursor: pointer; 
} 

.dropped { 
    background-color: #FC0; 
} 

.somethingover { 
    background-color: #FCD; 
} 

JS

var dragged, mousex, mousey, coordinates = []; 

var continueDragging = function(e) { 
    // Change the location of the draggable object 
    dragged.css({ 
     "left": e.pageX - (dragged.width()/2), 
     "top": e.pageY - (dragged.height()/2) 
    }); 

    // Check if we hit any boxes 
    for (var i in coordinates) { 
     if (mousex >= coordinates[i].left && mousex <= coordinates[i].right) { 
      if (mousey >= coordinates[i].top && mousey <= coordinates[i].bottom) { 
       // Yes, the mouse is on a droppable area 
       // Lets change the background color 
       coordinates[i].dom.addClass("somethingover"); 
      } 
     } else { 
      // Nope, we did not hit any objects yet 
      coordinates[i].dom.removeClass("somethingover"); 
     } 
    } 

    // Keep the last positions of the mouse coord.s 
    mousex = e.pageX; 
    mousey = e.pageY; 
} 

var endDragging = function(e) { 
    // Remove document event listeners 
    $(document).unbind("mousemove", continueDragging); 
    $(document).unbind("mouseup", endDragging); 

    // Check if we hit any boxes 
    for (var i in coordinates) { 
     if (mousex >= coordinates[i].left && mousex <= coordinates[i].right) { 
      if (mousey >= coordinates[i].top && mousey <= coordinates[i].bottom) { 
       // Yes, the mouse is on a droppable area 
       droptarget = coordinates[i].dom; 
       droptarget.removeClass("somethingover").addClass("dropped"); 
       dragged.hide("fast", function() { 
        $(this).remove(); 
       }); 
      } 
     } 
    } 

    // Reset variables 
    mousex = 0; 
    mousey = 0; 
    dragged = null; 
    coordinates = []; 
} 

var startDragging = function(e) { 
    // Find coordinates of the droppable bounding boxes 
    $(".droppable").each(function() { 
     var lefttop = $(this).offset(); 
     // and save them in a container for later access 
     coordinates.push({ 
      dom: $(this), 
      left: lefttop.left, 
      top: lefttop.top, 
      right: lefttop.left + $(this).width(), 
      bottom: lefttop.top + $(this).height() 
     }); 
    }); 

    // When the mouse down event is received 
    if (e.type == "mousedown") { 
     dragged = $(this); 
     // Change the position of the draggable 
     dragged.css({ 
      "left": e.pageX - (dragged.width()/2), 
      "top": e.pageY - (dragged.height()/2), 
      "position": "absolute" 
     }); 
     // Bind the events for dragging and stopping 
     $(document).bind("mousemove", continueDragging); 
     $(document).bind("mouseup", endDragging); 
    } 
} 

// Start the dragging 
$(".draggable").bind("mousedown", startDragging); 
+0

Początkowo byłem trochę sceptyczny, ale ta technika sprawdziła się bardzo dobrze - dziękuję bardzo! – OrganicPanda

+0

świetne rozwiązanie! dzięki !! – Denis

3

Istnieją dwa podstawowe sposoby, można to zrobić:

  1. utwór mousemove i reagować na x/y współrzędne
  2. mieć przejrzysty cel, który ma wyższy z-index niż pojemnika drag

Pierwsza opcja w rzeczywistości nie używa zdarzenia mouseover, ale daje taki sam wynik netto.

Należy pamiętać, że niektóre przeglądarki (np.) Nie będą wyzwalać mouseover na przezroczystych elementach, więc należy je sfałszować, ustawiając przezroczysty obraz tła lub ustawiając losowy obraz jako tło i umieszczając go poza elementem takim jak ten :

element { 
background: url(/path/to/img) no-repeat -10000px 0; 
} 
+0

To * może * zakłócać przeciągany element, w zależności od konfiguracji. – Purag

0

Modifing kawałek kodu zamieszczonych przez emrahgunduz, specjalnie dla pętli, można również zarządzać zagnieżdżony obszar droppable.

var dragged, mousex, mousey, coordinates = []; 

var continueDragging = function(e) { 
    // Change the location of the draggable object 
    dragged.css({ 
     "left": e.pageX - (dragged.width()/2), 
     "top": e.pageY - (dragged.height()/2) 
    }); 

    // Check if we hit any boxes 
    for (var i = coordinates.length - 1; i >= 0; i--) { 
     if (mousex >= coordinates[i].left && mousex <= coordinates[i].right) { 
      if (mousey >= coordinates[i].top && mousey <= coordinates[i].bottom) { 
       // Yes, the mouse is on a droppable area 
       // Lets change the background color 
       $('.droppable').removeClass("somethingover"); 
       coordinates[i].dom.addClass("somethingover"); 
       break; 
      } 
     } else { 
      // Nope, we did not hit any objects yet 
      coordinates[i].dom.removeClass("somethingover"); 
     } 
    } 

    // Keep the last positions of the mouse coord.s 
    mousex = e.pageX; 
    mousey = e.pageY; 
}; 

var endDragging = function(e) { 
    // Remove document event listeners 
    $(document).unbind("mousemove", continueDragging); 
    $(document).unbind("mouseup", endDragging); 

    // Check if we hit any boxes 
    for (var i = coordinates.length - 1; i >= 0; i--) { 
     if (mousex >= coordinates[i].left && mousex <= coordinates[i].right) { 
      if (mousey >= coordinates[i].top && mousey <= coordinates[i].bottom) { 
       // Yes, the mouse is on a droppable area 
       droptarget = coordinates[i].dom; 
       droptarget.removeClass("somethingover").addClass("dropped"); 
       dragged.hide("fast", function() { 
        $(this).remove(); 
       }); 
      } 
     } 
    } 

    // Reset variables 
    mousex = 0; 
    mousey = 0; 
    dragged = null; 
    coordinates = []; 
}; 

var startDragging = function(e) { 
    // Find coordinates of the droppable bounding boxes 
    $(".droppable").each(function() { 
     var lefttop = $(this).offset(); 
     // and save them in a container for later access 
     coordinates.push({ 
     dom: $(this), 
     left: lefttop.left, 
     top: lefttop.top, 
     right: lefttop.left + $(this).width(), 
     bottom: lefttop.top + $(this).height() 
    }); 
}; 

// When the mouse down event is received 
if (e.type == "mousedown") { 
    dragged = $(this); 
    // Change the position of the draggable 
    dragged.css({ 
     "left": e.pageX - (dragged.width()/2), 
     "top": e.pageY - (dragged.height()/2), 
     "position": "absolute" 
    }); 
    // Bind the events for dragging and stopping 
    $(document).bind("mousemove", continueDragging); 
    $(document).bind("mouseup", endDragging); 
} 

// Start the dragging 
$(".draggable").bind("mousedown", startDragging); 
6

We wszystkich przedstawionych odpowiedziach nie widzę najbardziej prostego i oczywistego (być może brakuje mi czegoś w pytaniu OP). Ale jeśli ktoś potknie to później, i wymaga szybkiego i prostego rozwiązania w czystym JS ..

to zrobić poprzez zmianę elementu className onDragOver, zmiana z powrotem do oryginalnej klasy ondragleave

my_element.ondragover = function(ev) { 
ev.preventDefault(); 
this.className = 'myElem_dragover'; 
} 
my_element.ondragleave = function(ev) { 
ev.preventDefault(); 
this.className = 'myElem_orig'; 
} 

CSS

.myElem_orig {  //this is your initial class for element 
    top: 30px; 
    left: 20px; 
    ..... 
    background-color: blue; 
} 

.myElem_orig:hover { //this is hover state, just changing bg color 
    background-color: red; 
} 

.myElem_dragover { //new class, needs all attributes from original class 
    top: 30px; 
    left: 20px; 
    ........ 
    background-color: red; //behaves the same like hover does 
} 

edit:
zapomniał ment jon, musisz przywrócić oryginalną klasę ondrop, inaczej div pozostanie w klasie dragover

+1

Myślę, że to pytanie poprzedza powszechne stosowanie wbudowanego atrybutu przeciągania HTML, co jest zdecydowanie najłatwiejszym sposobem, chyba że robisz niestandardowe zachowania. –

+0

Tego właśnie szukałem, a nie żadnego niestandardowego zachowania. Dzięki. – Wellyngton

+0

Zgadzam się z greg. Ta odpowiedź jest teraz znakomita i wkrótce zacznie być popularna. –

0

Znaleziono mały błąd w przykładzie jsfiddle. Po opuszczeniu obszaru opadania w pionie, obszar upuszczania nadal zawiera klasę "cośhover".

http://jsfiddle.net/MAazv

zastąpienie tego

if (mousex >= coordinates[i].left && mousex <= coordinates[i].right) { 
 
    if (mousey >= coordinates[i].top && mousey <= coordinates[i].bottom) { 
 
    // Yes, the mouse is on a droppable area 
 
    // Lets change the background color 
 
    coordinates[i].dom.addClass("somethingover"); 
 
    } 
 
} else { 
 
    // Nope, we did not hit any objects yet 
 
    coordinates[i].dom.removeClass("somethingover"); 
 
}

http://jsfiddle.net/MAazv/122

z tym:

if (mousex >= coordinates[i].left && mousex <= coordinates[i].right && mousey >= coordinates[i].top && mousey <= coordinates[i].bottom) { 
 
    // Yes, the mouse is on a droppable area 
 
    // Lets change the background color 
 
    coordinates[i].dom.addClass("somethingover"); 
 
} else { 
 
    // Nope, we did not hit any objects yet 
 
    coordinates[i].dom.removeClass("somethingover"); 
 
}

Powiązane problemy