当元素被禁用时触发 onmouseover 事件

Posted

技术标签:

【中文标题】当元素被禁用时触发 onmouseover 事件【英文标题】:Fire onmouseover event when element is disabled 【发布时间】:2013-08-09 10:51:27 【问题描述】:

当用户没有编辑权限时,我需要禁用一些控件,但有时它们的宽度不足以显示所选选项元素的整个文本。在这种情况下,我添加了一个带有 ASP.NET 的工具提示和以下代码

ddl.Attributes.Add("onmouseover", "this.title=this.options[this.selectedIndex].title")

这在控件启用时有效,但在禁用时无效。

当鼠标悬停在选择元素上时,不会触发以下警报:

<select disabled="disabled" onmouseover="alert('hi');">
    <option>Disabled</option>
</select>

看到这个fiddle

我可以为disabled 的控件触发onmouseover 事件吗?

【问题讨论】:

Fiddle 中的禁用按钮计数器正在为我触发 Chrome 93 和 Firefox 91。这里有警报(适用于 Firefox 91 但不适用于 Chrome 93):jsfiddle.net/7hqL2f1a/1 【参考方案1】:

禁用的元素不会触发事件,例如用户不能悬停或单击它们来触发弹出框(或工具提示)。但是,您可以使用 DIV 包装禁用的元素,并改为监听在该元素上触发的事件。

【讨论】:

你能演示一下吗 看来如果disabled元素占据了100%的div,即使这样也行不通 这样做并使用“mouseenter”而不是“mouseover”,它会起作用。 问题是一旦启用按钮,您就会丢失 html 'not-allowed' 光标 snf 指针光标【参考方案2】:

更新:请参阅nathan william's comment 了解此方法的一些严重限制。我已经更新了小提琴以更清楚地说明问题区域。


扩展 @Diodeus 所说的内容,您可以使用 jQuery 自动为您创建 div 容器并将其包裹在任何禁用的元素周围。

    使用:disabled 选择器查找所有禁用的元素。 然后用函数回调调用.wrap()方法 您可以使用 this 来引用集合中的当前元素。 然后使用.attr() 方法从父元素中获取onmouseover 值,并将相同的值应用到新的div。
$(':disabled').wrap(function() 
    return '<div onmouseover="' + $(this).attr('onmouseover') + '" />';
);

Demo in jsFiddle

【讨论】:

应该注意,禁用元素本身仍然存在死区。如果包装器有块样式,那么效果会不稳定;如果它具有内联样式,则鼠标可能永远不会通过它的任何部分来触发效果。 z-index 覆盖元素的行为会更加一致,但需要插入一个相对于包装器具有绝对定位的兄弟元素。【参考方案3】:

我知道这是一篇旧帖子,但希望这个答案能够阐明如何实现@Diodeus 答案!

禁用的元素不会触发事件,例如用户不能悬停或单击它们来触发弹出框(或工具提示)。但是,作为一种解决方法,您可以将 &lt;DIV&gt;&lt;span&gt; 包裹在禁用的元素周围,然后改为监听在该元素上触发的事件。

注意!在包装器 &lt;DIV&gt; 中使用 onmouseoveronmouseout 在 Chrome (v69) 中将无法正常工作。但将在 IE 中工作。这就是为什么我建议用户改用 onmouseenteronmouseleave,这在 IE 和 Chrome 中都很好用。

   <select disabled="disabled" onmouseover="alert('hi');">
    <option>Disabled</option>
  </select>

  <div onmouseenter="alert('hi');">
    <select disabled="disabled" onmouseover="alert('hi');">
      <option>Disabled with wrapper</option>
    </select>
  </div>

我在这里整理了一个带有一些示例的 JS 小提琴:http://jsfiddle.net/Dr4co/tg6134ju/

【讨论】:

感谢您添加此答案。在最新版本的 Chrome 中,onmouseenter 确实可以用disabled 子代代替onmouseover,但onmouseleave 不能代替onmouseout。由于onmouseleave 的问题,我仍然必须在位于disabled 子元素顶部的包装器中添加一个::before 伪元素,以便触发onmouseoveronmouseleave【参考方案4】:

我知道这是一篇旧帖子,但在 chrome 中,您可以将 css 属性指针事件设置为 all,它应该允许事件。我没有在其他浏览器中检查过。

button[disabled] 
  pointer-events: all;

编辑:

其实我认为将属性设置为 auto 就足够了。正如@KyleMit 评论的那样,支持它非常好。

我刚刚在项目中使用了这个,我需要禁用一个按钮,直到满足一些验证规则,但我还需要在将鼠标悬停在按钮上时触发验证。所以添加指针事件就可以了。我认为这是解决 OP 中所述问题的最简单方法。

【讨论】:

无论我使用all 还是auto,这对我都不起作用。【参考方案5】:

为什么不能在目标元素上添加标题? 标题看起来与工具提示相同。 并且标题适用于禁用的元素。

当你设置你的选择值时,还要设置标题:

element.value=value;
element.title = element.options[element.selectedIndex].text;

【讨论】:

贾斯汀,这是一种方法(我想我最终可能会选择)——问题是有很多选择被有条件地禁用。我需要鼠标悬停,以便标题在它没有被禁用时会适当更新。但是用正确的标题播种它涵盖了这两种情况。 到 Kylemit,然后你可以为它添加条件: if(element.classList.contains("addTitle15")) // 添加标题【参考方案6】:

有两种解决方案

<Tooltip title="Tooltip" placement="bottom">
          <div>
            <IconButton disabled>
              <Done />
            </IconButton>
          </div>
        </Tooltip>

如果你不想错过这个视图,也可以选择这个

<Tooltip title="Tooltip" placement="bottom">
  <IconButton component="div" disabled>
    <Done />
  </IconButton>
</Tooltip>

reference

【讨论】:

以上是关于当元素被禁用时触发 onmouseover 事件的主要内容,如果未能解决你的问题,请参考以下文章

JS中onmouseover与onmouseout的bug

事件对象1

解决内部元素onMouseOver/onMouseOut事件冒泡触发父元素的相应事件

常见事件总结

JS事件 鼠标经过事件(onmouseover)鼠标经过事件,当鼠标移到一个对象上时,该对象就触发onmouseover事件,并执行onmouseover事件调用的程序。

JS事件