event.clientX在firefox中显示为0表示dragend事件

Mag*_*sso 13 javascript drag-and-drop mouse-position

function move(e,obj,but){
    if(typeof(obj) === 'string'){
        obj = document.getElementById(obj) ;
    }

    if(typeof(but) === 'string'){
        but = document.getElementById(but) ;
    }

    //elementCoord(but) ;//get the current coords of the button &
    elementCoord(obj) ;//the container

    e = e || window.event ;
    var mouseX = e.clientX ;
    var mouseY = e.clientY ;

    //alert('mouseX='+mouseX+', but.XCoord '+but.XCoord) ;
    var diffX = Math.abs(obj.XCoord - mouseX) ;
    var diffY = Math.abs(obj.YCoord - mouseY) ;

    but.addEventListener("dragend",function(evt){
        evt = evt || window.event ;
        mouseX = evt.clientX ;
        mouseY = evt.clientY ;
        obj.style.left = mouseX - diffX + 'px';
        obj.style.top = mouseY - diffY + 'px';
        alert('mouseX='+mouseX+' diffX='+diffX) ;
        }
    ,false) ;

}
Run Code Online (Sandbox Code Playgroud)

来自dragend的警报显示mouseX为零,无论它当前在何处.这在Chrome中运行良好,所以不确定我做错了什么.

忘记提及,elementCoord只获取一个对象的偏移量,将其添加为属性.它适用于所有浏览器.

Hol*_*ger 11

这是 Firefox 的正式问题 - Bugzilla:Bug #505521,在 HTML5 拖动事件期间设置屏幕坐标。我将引用 jbmj 进行总结,并且我将粗体显示他们引用的原始开发人员......

我不敢相信 11 年前的这条评论
请注意,虽然它没有指定属性应该设置什么,只是应该设置它们,而我们目前将它们设置为 0。
仍然是最先进的。

我受到杰伊评论的启发,使用了“drop”事件。但这只是一个评论,所以让我把它整理成一个答案。

我们的问题:dragend事件已e.clientY设置e.clientX为 0。

我们将如何解决这个问题:documentdrop事件也会与我们拖动的元素的事件同时触发dragend。And:将具有drop 的正确值。e.clientYe.clientX

两个工作演示,100% 仅 JavaScript 解决方案:SO 代码片段和JSBin。SO 代码片段控制台有时会吞噬控制台中拖动的元素,而 JSBin 给了我更一致的结果。

var startx = 0;
var starty = 0;
dragStartHandler = function(e) {
  startx = e.clientX;
  starty = e.clientY;
}

dragOverHandler = function(e) {
  e.preventDefault();
  return false;
}

dragEndHandler = function(e) {
  if(!startx || !starty) {
    return false;
  }
  
  var diffx = e.clientX - startx;
  var diffy = e.clientY - starty;
  
  var rect = e.target.getBoundingClientRect();

var offset = { 
                top: rect.top + window.scrollY, 
                left: rect.left + window.scrollX, 
            };
  
  var newleft = offset.left + diffx;
  var newtop = offset.top + diffy;
  
  e.target.style.position = 'absolute';
  e.target.style.left = newleft + 'px';
  e.target.style.top = newtop + 'px';
  
  startx = 0;
  starty = 0;
}

document.getElementsByClassName("draggable")[0].addEventListener('dragstart', dragStartHandler);

document.addEventListener('dragover', dragOverHandler);
document.addEventListener('drop', dragEndHandler);
Run Code Online (Sandbox Code Playgroud)
.draggable {
  border: 1px solid black;
  cursor: move;
  width:250px;
};
Run Code Online (Sandbox Code Playgroud)
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>
<body>
  
  <BR><BR><BR>

  <div id="draggable1" class="draggable" draggable="true">
    Hey, try to drag this element!
  </div>
  
</body>
</html>
Run Code Online (Sandbox Code Playgroud)

解释:

  • dragStartHandler():这绑定到可拖动元素。在这里,我们所做的就是在开始时记录当前的 x/y 坐标。
  • dragOverHandler():这与文档绑定,以便我们可以覆盖默认的拖动行为。这是进行任何类型的拖放操作所必需的。
  • dragEndHandler():这个是绑定documentdrop。通常,我们希望将其绑定到element's dragend,但由于缺少clientYclientX,我们将其绑定到文档。这正是您在调用 Dragend 时想要发生的事情,除非您有 x/y 坐标。


ale*_*don 10

Firefox有一个关于拖动事件未提供用户指针信息的老错误

\n

我发现 Firefox 中几乎所有与拖动相关的事件现在都会发布用户指针信息:

\n
    \n
  • \xe2\x9c\x85"dragstart"
  • \n
  • \xe2\x9c\x85"dragenter"
  • \n
  • \xe2\x9c\x85"dragleave"
  • \n
  • \xe2\x9c\x85"dragover"
  • \n
  • \xe2\x9c\x85"drop"
  • \n
  • \xe2\x9c\x85"dragend"
  • \n
  • \xe2\x9d\x8c"drag"
  • \n
\n
\n

在 Firefox 99 版本中测试

\n
\n

所以回答原来的问题:event.clientX将不再总是0dragendFirefox 中

\n
\n

如果您需要在拖动过程中获取指针信息(即"drag"通常会提供给您的信息),那么您可以执行以下操作:

\n
    \n
  1. 添加一个事件监听器到相当高的EventTarget(例如window)并监听"dragover"事件。
  2. \n
\n
    \n
  • dragover每当你超过潜在的掉落目标时就会触发,这是每个Element
  • \n
  • 通过向高位添加事件侦听器EventTarget(例如window),您可以利用事件冒泡来捕获高位中dragover所有Elements的所有事件。document
  • \n
\n
    \n
  1. 利润:drag通过重新利用有效地获得事件dragover
  2. \n
\n
window.addEventListener(\'dragover\', (event) => {\n  // event.clientX and friends are correctly set!\n});\n
Run Code Online (Sandbox Code Playgroud)\n

  • 这救了我的命! (2认同)

小智 -2

不要使用 e.clientX 或 e.clientY

请改用 e.pageX 和 e.pageY 或 e.targetTouches[0].pageX e.targetTouches[0].pageY(对于触摸屏)。

pageX 指的是文档,clientX 指的是视口。也可以看看:

https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/pageX https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/clientX