Как запустить событие наведения мыши при перетаскивании - PullRequest
26 голосов
/ 23 декабря 2011

Когда я перетаскиваю элемент поверх другого div, на котором у меня есть событие наведения мыши, событие не срабатывает.Тем не менее, это работает, если я наведите курсор мыши на него, не перетаскивая.

Есть ли способ обнаружить всплывающие события на элементе, если я перетаскиваю другой элемент поверх него?

Ответы [ 6 ]

13 голосов
/ 23 декабря 2011

Вот пример с использованием решения координат XY.

Рабочий пример для jsfiddle

Этот пример можно улучшить, но он является хорошей отправной точкой.

Просто отслеживает местоположение мыши и проверяет, находится ли она внутри каких-либо ограничивающих рамок предметов, которые могут быть сброшены.Следовательно, если событие mouseup срабатывает на любом из них, перетаскиваемый объект отбрасывается.

Вы также можете использовать координаты перетаскиваемого объекта для обнаружения, если он находится на выпадающем блоке, но это требует немногомне достаточно кода для нахождения координат ограничивающего прямоугольника и использования мыши.

Код использует jQuery, но не jQueryUI.Я тестировал в Chrome, Firefox и Opera, но не в IE:)

Я также добавляю сюда код, если jsfiddle недоступен.

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);
8 голосов
/ 20 сентября 2014

Во всех представленных ответах я не вижу самого простого и очевидного (возможно, я что-то упускаю в OP-вопросе). Но, если кто-то наткнется на это позже и нуждается в быстром и простом решении на чистом JS ..

Вы делаете это, изменяя элемент className ondragover и возвращаясь к исходному классу 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
}

редактирование:
забыл упомянуть, вам нужно вернуть оригинальный класс ondrop , иначе div останется в классе dragover

3 голосов
/ 23 декабря 2011

Есть два основных способа сделать это:

  1. отслеживать mousemove и реагировать на координаты х / у
  2. иметь прозрачную цель с большей z-indexчем контейнер перетаскивания

Первый вариант на самом деле вообще не использует событие mouseover, но даст тот же чистый результат.

Помните, что некоторые браузеры (то есть) выигралине запускайте mouseover на прозрачных элементах, поэтому вам нужно подделать его, установив прозрачное фоновое изображение или выбрав случайное изображение в качестве фона, и расположив его вне элемента следующим образом:

element {
 background: url(/path/to/img) no-repeat -10000px 0;
}
1 голос
/ 24 февраля 2013

jQuery-ui имеет плагин для этого.

Плагин, когда используется с перетаскиваемым элементом , вызовет dropover событий, которые могут быть связаны с любым действием, которое вам требуется.

См. Ответ Моттина этот вопрос (демо включено)

0 голосов
/ 26 ноября 2015

Нашли небольшую ошибку в примере с jsfiddle.Когда вы покидаете область перетаскивания вертикально, область перетаскивания по-прежнему имеет класс «Somehover».

http://jsfiddle.net/MAazv

Заменить

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

с этим:

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");
}
0 голосов
/ 20 декабря 2013

Немного изменив код, отправленный emrahgunduz, в частности цикл for, вы также можете управлять вложенной областью сброса.

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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...