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

时间:2012-07-25 18:17:00

标签: 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) ;

}

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

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

4 个答案:

答案 0 :(得分:0)

请勿使用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

答案 1 :(得分:0)

前几天,我在Firefox中遇到了同样的问题。

我设法找到了解决方法,尽管它依赖于使用全局变量在位置前后存储鼠标。

似乎起作用的一点是从ondrop事件而不是ondragend事件中获取pageX和pageY值。

唯一的问题是,放置位置不存储拖动的元素或原始鼠标位置(因此需要全局变量)。

var dragDetails = {
   target: null,
   orgMouseX: 0,
   orgMouseY: 0,
   desMouseX: 0,
   desMouseY: 0
}

$("targetElement").on("dragstart", function(event) {
   dragDetails.target = this;
   dragDetails.orgMouseX = event.originalEvent.pageX;
   dragDetails.orgMouseY = event.originalEvent.pageY;
});

$("html").on("drop", function(event) {
   dragDetails.desMouseX = event.originalEvent.pageX;
   dragDetails.desMouseY = event.originalEvent.pageY;
   handleDrag();
});

下面是一个小提琴的例子:https://jsfiddle.net/L1b6uz2d/2/

它似乎可以在最新版本的Chrome,Firefox,Edge和Internet Explorer上运行(尽管在Internet Explorer上准确性不高),并且在Android Chrome上也可以运行。还没有测试其他任何东西,我敢肯定代码可以改进。

我确实设法在不需要全局变量的情况下使其正常运行,但是我不得不使用ondrop,然后将目标,pageX和pageY传递给ondragend事件的参数(我没有提供小提琴,因为代码非常难看)

答案 2 :(得分:0)

document.addEventListener("dragover", function( event ) { event.preventDefault(); console.log(event.pageX) }, false);

在拖曳侦听器中添加console.log(event.pageX) http://jsfiddle.net/zfnj5rv4/

答案 3 :(得分:0)

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

我不敢相信这个评论
请注意,尽管它没有指定应将属性设置为什么,而只是指定了属性,并且我们当前将它们设置为0。
距11年前还很先进。

Jay的评论启发了我使用“ drop”事件。但这只是评论,所以让我将其脱颖而出作为答案。

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

我们将如何解决它:document的{​​{1}}事件也会在与拖动元素的drop事件相同的确切时间触发。并且:dragend 将具有drope.clientY的正确值。

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

e.clientX
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>:这绑定到可拖动元素。在这里,我们要做的就是在开始时记录当前的x / y坐标。
  • dragStartHandler():这绑定到文档,因此我们可以覆盖默认的拖拽行为。进行任何类型的拖放都是必需的。
  • dragOverHandler():这绑定到dragEndHandler()的{​​{1}}。通常,我们希望将其绑定到document的{​​{1}},但是由于缺少dropelement,因此将其绑定到文档。这恰好满足了在调用dragend时想要发生的事情,除了您有x / y坐标。