javascript - 为什么 event.clientX 在 firefox 中对于 dragend 事件错误地显示为 0?

标签 javascript drag-and-drop mouse-position

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

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

忘记提及,elementCoord 只是获取对象的偏移量并将其添加为属性。它在所有浏览器中都能正常工作。

最佳答案

这是 Firefox 的正式问题 -- Bugzilla: Bug #505521, Set screen coordinates during HTML5 drag event .我将引用 jbmj 进行总结,并将他们引用的原始开发人员加粗...

I can't believe that this comment
"Note though that it doesn't specify what the properties should be set to, just that they should be set and we currently set them to 0."
from 11years ago is still state of the art.

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

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

我们将如何解决它:documentdrop 事件 也会在我们拖动的元素的 的同一时间触发>dragend 事件。并且:drop将为 e.clientYe.clientX 提供正确的值。

两个工作演示,100% 纯 JavaScript 解决方案:SO 代码片段和 JSBin . SO Code Snippet 控制台有时会吞噬控制台中拖动的元素,而 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);
.draggable {
  border: 1px solid black;
  cursor: move;
  width:250px;
};
<!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>

解释:

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

关于javascript - 为什么 event.clientX 在 firefox 中对于 dragend 事件错误地显示为 0?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11656061/

相关文章:

java - SWT DragSourceEvent 图像未正确锚定到鼠标指针

wpf - 如何在 Blend 中将径向渐变的 X/Y 坐标数据绑定(bind)到鼠标光标的 X/Y 坐标?

javascript - 查询字符串更改时重新渲染 React 组件

c# - 在 JavaScript 中将 C# .NET DateTime.ticks 转换为天/小时/分钟

reactjs - react-beautiful-dnd:无法在 Draggable 中找到拖动 handle 元素

html - 拖放区的视觉 HTML5 效果不错?

javascript - 确定鼠标位置是否靠近浏览器的边缘

Javascript 使用鼠标坐标旋转图像

javascript - 在处理 React.js 元素时是否建议编辑 index.html 文件?

javascript - 如何申请:hover on :after to certain div in CSS