《JavaScript权威指南》P462 例17-2 拖动文档元素的例子中
对于mousemove和mouseup事件有这样的描述
值得注意的是mousemove和mouseup处理程序注册为捕获事件处理程序。这是因为用户可能移动鼠标比其后的文档元素更快,如果这种情况发生,某些mousemove事件会发生在原始目标元素之外。没有捕获,这些事件将无法分派正确的处理程序。
但是本人经过测试,只要在触发mousedown事件之后将mousemove和mouseup注册在document对象上,就可以实现功能,无论是事件冒泡阶段还是事件捕获阶段。
document.addEventListener("mousemove", moveHandler, true);
document.addEventListener("mouseup", upHandler, true);
或者
document.addEventListener("mousemove", moveHandler, false);
document.addEventListener("mouseup", upHandler, false);
Drag.js
function drag(elementToDrag, event){
var scroll = getScrollOffsets();
var startX = scroll.x + event.clientX;
var startY = scroll.y + event.clientY;
var oriX = elementToDrag.offsetLeft;
var oriY = elementToDrag.offsetTop;
var deltaX = startX - oriX;
var deltaY = startY - oriY;
console.log(1);
document.addEventListener("mousemove", moveHandler, true);
document.addEventListener("mouseup", upHandler, true);
if(event.stopPropagation)
event.stopPropagation();
else
event.cancelBubble = true;
if(event.preventDefault)
event.preventDefault();
else
event.returnValue = false;
function moveHandler(e){
var scroll = getScrollOffsets();
elementToDrag.style.left = (e.clientX + scroll.x - deltaX) + "px";
elementToDrag.style.top = (e.clientY + scroll.y - deltaY) + "px";
console.log(2);
if(e.stopPropagation)
e.stopPropagation();
else
e.cancelBubble = true;
}
function upHandler(e){
document.removeEventListener("mousemove", moveHandler, true);
document.removeEventListener("mouseup", upHandler, true);
console.log(3);
if(e.stopPropagation)
e.stopPropagation();
else
e.cancelBubble = true;
}
}
所以我并没有明白书上的意思啊,究竟是我考虑的不周到,还是注册在两个阶段根本没有区别呢?
谈谈我的理解
首先这里翻译有误,
这是因为用户可能移动鼠标比其后的文档元素更快
这句话的原文如下:
because the user may move the mouse faster than the document element can follow it
其实在说这样的情况,鼠标移动的速度很快,而被拖动的元素跟不上鼠标的速度。
了解了这句话之后,就去分析,addEventListener方式其实对capture或者bubble都无影响,因为反正都是监听在document之上,不管鼠标多快,不管是不是超出目标元素的范围,mousemove事件都会发生,所以总会把目标元素移动到指定鼠标的位置
在我看来,这里的考虑是针对elementToDrag.attachEvent()
这种方式的事件绑定,因为它将mousemove事件直接绑定在了目标元素上,那么如果鼠标移动太快,而元素没有跟上,那么mousemove事件就不会再目标元素身上发生,就触发不了处理函数。
但是其实使用capture阶段的,只是比bubble阶段调用处理函数敏捷(快)了一点,依旧会出现目标元素更不上的情况