在Firefox中,onDrag事件的clientX始终为0。

3

我在codesandbox.io上创建了一个视频播放器进度条(https://codesandbox.io/s/seekbar-with-thumbnail-and-time-tooltips-forked-h5x8k?file=/src/Progressbar.tsx),在Chrome浏览器上可以正常工作,但在其他浏览器上无法工作。

特别是在Firefox浏览器上进度条滑块不起作用,dragStart和dragEnd事件能够正常触发,但onDrag事件不能。

onDrag事件的clientX、clientY等所有值都是错误的。

通过一些搜索,我发现了有关dataTransfer的信息,并将其添加到了drag start事件处理程序中...

event.dataTransfer.setData("application/x-moz-node", event.target.id);

我在我的dragEnd事件处理程序中使用了event.preventDefault(),但结果仍然相同。

有人能帮帮我吗?

完整的代码可在我上面粘贴的codesandbox链接中找到。

编辑:拖动事件正在触发,但以下属性每次都相同

screenX: 0

screenY: 0

clientX: 0

clientY: 0

pageX: 0

pageY: 0

是什么导致了这个问题?为什么全部都是0?


你确定 drag 事件没有被触发吗?我这里它是被触发了,尽管 clientX 的值为 0,因此没有通过 if 条件。 - Dan Macak
嘿@DanMacák,你是对的,拖动事件确实在触发,但所有值(clientX、clientY等)都为0。那么如何在Firefox中实现滑块?已经有这么多UI库中的滑块了...你有任何想法吗? - stackboy
我的猜测是这些库使用基于指针而非基于拖动的方法。让我在回答中详细解释一下。 - Dan Macak
3个回答

1
在Firefox中,您可以在拖动事件触发之前设置 dataTransfer
d = document.getElementById('d');

d.addEventListener('drag', function(e){
    console.log("drag:", e)
});

d.addEventListener('dragstart', function(e){
    e.dataTransfer.setData('application/node type', this);
    console.log("dragstart:", e)
});

你可以在这个链接中查看推荐的拖拽类型拖拽类型

嘿@Morteza,我已经在设置dataTransfer了,我也更新了我的问题。 - stackboy

1

event.dataTransfer在这里不相关,实际问题是Firefox在drag事件期间不跟踪指针位置。要了解原因,请查看这个很好的答案,该问题类似于您的问题。

这意味着您无法使用drag根据拖动它的指针来更新元素的位置。相反,您可以使用dragover

document.addEventListener('dragover', updateProgress)

与拖动不同,dragover 跟踪指针位置,因此您可以使用它来更新滑块的位置。但是有一个问题。在您的页面上,可能会有多个可拖动元素,因此您可能需要在 ondragover 监听器中检查正在拖动哪个元素。但是您不能轻易地这样做,因为 documentdragover 的目标,而不是被拖动的元素。因此,一旦触发了 dragstart,您还需要检查正在拖动哪个元素,并在 dragend 上清理 ondragover 监听器。

另一种选择是使用 Pointer events API,特别是 pointerdownpointermovepointerup。实现的工作量类似,但是 Pointer events 应该在浏览器(与 drag 事件相反)和设备之间更加一致,因为 Pointer events 将许多种输入 - 触摸、鼠标、笔 - 统一到单个 API 后面。


你是否有一个好的例子可以详细说明指针事件?我也遇到了拖放的问题,但是当你试图摆脱它时,你必须注意很多事情。 - frans

0
你可以通过拥有一个保存当前鼠标位置的全局对象来解决这个问题。
    var mousePosition = {
        x: 0,
        y: 0,
    }

同时使用mousemove事件和dragover事件进行更新。由于拖动时mousemove事件不会触发,因此我们依靠dragover事件监听器进行更新,因为它具有event.clientY。

   document.addEventListener("mousemove", function (event) {
        mousePosition.x = event.clientX;
        mousePosition.y = event.clientY;
    });

   document.addEventListener("dragover", function (event) {
        mousePosition.x = event.clientX;
        mousePosition.y = event.clientY;
    })

因此,您可以在任何需要获取鼠标位置的地方使用mousePosition对象。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接