当我将一个元素拖动到另一个具有mouseover事件的
上时,该事件不会触发。但是,如果我悬停在其上而不拖动,则可以正常工作。
如果我拖动另一个元素到它上面,有没有一种方法来检测它上面的hover事件?
当我将一个元素拖动到另一个具有mouseover事件的
如果我拖动另一个元素到它上面,有没有一种方法来检测它上面的hover事件?
my_element.ondragover = function(ev) {
ev.preventDefault();
this.className = 'myElem_dragover';
}
my_element.ondragleave = function(ev) {
ev.preventDefault();
this.className = 'myElem_orig';
}
.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 类名下
dragOver
事件中,您可以测试鼠标位于上半部分还是下半部分,并根据此作出决策。使用object.getBoundingClientRect()
,例如,您可以获得底部边界并从中减去鼠标的Y坐标。您会得到一个比对象高度/2大或小的值。 - Wolf Wardragover
事件,谢谢。 - KeldericgetBoundingClientRect()
是拖放API的一部分,那么你就错了。实际上,在dragOver
事件中,你可以测试许多东西,其中之一就是边界矩形,并使用纯数学计算位置。 - Wolf War这里是使用X-Y坐标解决方案的示例。
示例可以改进,但是是一个很好的起点。
简单地跟踪鼠标位置并检查它是否出现在任何可拖放对象的边界框内。因此,如果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;
}
JavaScript
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);
有两种基本方法可以做到这一点:
mousemove
并根据x/y坐标做出反应z-index
高于拖动容器第一种选择实际上根本不使用mouseover
事件,但会给你相同的结果。
请注意,某些浏览器(ie)不会在透明元素上触发mouseover
事件,因此您必须通过设置透明的背景图像或将随机图像设置为背景并将其定位在元素外面来伪造它,就像这样:
element {
background: url(/path/to/img) no-repeat -10000px 0;
}
解决拖动元素阻塞下方元素的hover或mouseenter事件的另一个可能方法是:
pointer-events: none;
如果将此应用于拖动元素,则下方元素上的hover仍然可以正常工作。
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);
替换这个
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");
}
使用这个:
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");
}