Подтвердить что ты не робот

Как начать событие mouseover при перетаскивании

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

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

4b9b3361

Ответ 1

Вот пример использования решения X-Y.

Рабочий пример на 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);

Ответ 2

Во всех представленных ответах я не вижу самого простого и очевидного (возможно, что-то не хватает в вопросе ОП). Но, если кто-то наткнется на это позже и нуждается в быстром и простом решении в чистом 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

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

  • отслеживать mousemove и реагировать на координаты x/y
  • имеет прозрачную цель с более высоким z-index, чем контейнер перетаскивания

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

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

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

Ответ 5

Модифицируя код, отправленный emrahgunduz, в частности цикл for, вы также можете управлять вложенной областью 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

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

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");
}