使用JavaScript全局覆盖鼠标光标

n.d*_*dee 13 html javascript css mouse-cursor

在我的Web应用程序中,我尝试实现一些拖放功能.我有一个全局JavaScript组件,它完成了基本的工作.此对象还负责根据当前拖动操作(移动,复制,链接)更改鼠标光标.在我的网页上有各种HTML元素,它们可以内联或通过CSS文件定义自己的光标样式.

那么,我的中央拖放组件是否有办法全局更改鼠标光标,与鼠标光标所在元素的样式无关?

我试过了:

document.body.style.cursor = "move"
Run Code Online (Sandbox Code Playgroud)

document.body.style.cursor = "move !important"
Run Code Online (Sandbox Code Playgroud)

但它不起作用.每次我拖动一个定义光标样式的元素时,光标会变为该样式.

当然,我可以改变我正在拖动的元素的样式,但是当我对元素进行渲染时我必须重置它.这似乎有点复杂.我正在寻找全球解决方案.

Sam*_*lle 14

请:不要屠杀你的CSS!

要实现拖放功能,您必须使用非常重要的API:element.setCapture().这会产生这样的后果:

  • 所有鼠标事件都被重定向到捕获的目标元素,无论它们发生在何处(甚至在浏览器窗口之外)
  • 无论鼠标指针在哪里,光标都将成为捕获目标元素的光标.

您必须调用element.releaseCapture()document.releaseCapture()以在操作结束时切换回正常模式.

谨防拖放的天真实现:你可能会遇到很多痛苦的问题,例如(除其他外):如果鼠标在浏览器窗口之外被释放,或者在具有停止传播的处理程序的元素上会发生什么.使用setCapture()解决了所有这些问题,以及光标样式.

如果你想自己实现拖放,你可以阅读这篇优秀的教程,详细解释这一点.

也许你也可以在你的上下文中使用jQuery UI draggable.

  • setCapture在IE和FF/Moz中工作,但看起来Chrome不支持这个很棒的功能:( (5认同)
  • 2021 年(2020 年之后的另一边),Mozilla 文档说明了 https://developer.mozilla.org/en-US/docs/Web/API/Element/setCapture:“此功能是非标准的,不在标准轨道上. 不要在面向 Web 的生产站点上使用它:它不适用于每个用户。实现之间也可能存在很大的不兼容性,并且将来的行为可能会发生变化”。 (3认同)

Fel*_*ann 9

我尝试使用setPointerCapture效果很好。缺点是,(当然)所有指针事件都不会像以前那样工作。所以我失去了悬停样式等。

我现在的解决方案非常简单,对于我的用例来说,比上面的 CSS 解决方案更适合。

为了设置光标,我在头部添加了一个新的样式表:

const cursorStyle = document.createElement('style');
cursorStyle.innerHTML = '*{cursor: grabbing!important;}';
cursorStyle.id = 'cursor-style';
document.head.appendChild(cursorStyle);
Run Code Online (Sandbox Code Playgroud)

要重置它,我只需删除样式表:

document.getElementById('cursor-style').remove();
Run Code Online (Sandbox Code Playgroud)


Chr*_*oph 5

document.body.style.cursor = "move"
Run Code Online (Sandbox Code Playgroud)

应该工作正常。

但是,我建议通过CSS进行全局样式设置。

定义以下内容:

body{
   cursor:move;
}
Run Code Online (Sandbox Code Playgroud)

问题是,其他元素上定义的光标会覆盖主体样式。

您可以这样做:

your-element.style.cursor = "inherit"; // (or "default")
Run Code Online (Sandbox Code Playgroud)

将其重置为从正文或CSS继承的样式:

body *{
   cursor:inherit;
}
Run Code Online (Sandbox Code Playgroud)

但是请注意,*通常认为这是错误的选择器选择。


小智 5

不幸的element.setCapture()是不适用于 IE

我使用强力方法 - 在拖放期间在整个页面顶部打开一个透明 div。

.tbFiller {
   position:absolute;
   z-index:5000; 
   left:0;
   top:0;
   width:100%;
   height:100%; 
   background-color:transparent;
   cursor:move;
}

...

function dragStart(event) {
    // other code...
    document.tbFiller=document.createElement("div");
    document.tbFiller.className="tbFiller"
}

function dragStop(event) {
    // other code...
    document.tbFiller.parentNode.removeChild(document.tbFiller);
}
Run Code Online (Sandbox Code Playgroud)