如何在纯JavaScript中模拟鼠标悬停以激活CSS“:hover”?

时间:2013-06-21 02:08:21

标签: javascript jquery css

我一直在尝试在Chrome中找到模拟mouseover的代码,但即使“鼠标悬停”侦听器被触发,CSS“悬停”声明也永远不会设置!

我也尝试过:

//Called within mouseover listener
theElement.classList.add("hover");

但似乎没有任何东西将元素更改为hover声明中声明的内容。

这可能吗?

7 个答案:

答案 0 :(得分:90)

你做不到。这不是trusted event

  

用户代理生成的事件,无论是作为用户交互的结果,还是作为DOM更改的直接结果,都受到用户代理的信任,具有不通过脚本通过脚本生成的事件提供的特权。 DocumentEvent.createEvent(“Event”)方法,使用Event.initEvent()方法修改,或通过EventTarget.dispatchEvent()方法调度。受信任事件的isTrusted属性值为true,而不受信任事件的isTrusted属性值为false。

     

大多数不受信任的事件不应触发默认操作,但click或DOMActivate事件除外。

您必须手动添加一个类并在mouseover / mouseout事件上添加/删除它。

答案 1 :(得分:16)

背景

我在尝试编写自动化测试时偶然发现了这个问题,以验证所有接收到的给定页面上的某组元素是否具有由css为悬停事件设置的一些css属性集。

虽然上面的答案完美地解释了,为什么不可能简单地通过JS触发悬停事件然后证明一些感兴趣的css值,它确实回答了最初的问题"我如何模拟a鼠标悬停在纯JavaScript中激活CSS“:hover”?"只是部分。

声明

这不是一个高效的解决方案。我们仅将其用于自动化测试,而性能不是问题。

解决方案

simulateCssEvent = function(type){
    var id = 'simulatedStyle';

    var generateEvent = function(selector){
        var style = "";
        for (var i in document.styleSheets) {
            var rules = document.styleSheets[i].cssRules;
            for (var r in rules) {
                if(rules[r].cssText && rules[r].selectorText){
                    if(rules[r].selectorText.indexOf(selector) > -1){
                        var regex = new RegExp(selector,"g")
                        var text = rules[r].cssText.replace(regex,"");
                        style += text+"\n";
                    }
                }
            }
        }
        $("head").append("<style id="+id+">"+style+"</style>");
    };

    var stopEvent = function(){
        $("#"+id).remove();
    };

    switch(type) {
        case "hover":
            return generateEvent(":hover");
        case "stop":
            return stopEvent();
    }
}

说明

generateEvent读取所有css文件,替换:用空字符串悬停并应用它。这具有以下效果:应用所有:悬停样式。现在,可以通过停止模拟来探测啸叫风格并恢复到初始状态。

为什么我们将悬停效果应用于整个文档,而不仅仅是通过从工作表中获取感兴趣的元素然后执行element.css(...)?

完成后,样式将内联应用,这将覆盖其他样式,这些样式可能不会被原始的css悬停样式覆盖。

我现在如何模拟单个元素的悬停?

这不是高效的,所以最好不要这样做。如果必须,如果样式适用于您的元素并且仅使用这些样式,则可以使用element.is(selectorOfInterest)进行检查。

实施例

在Jasmine你可以,例如现在执行:

describe("Simulate CSS Event", function() {
    it("Simulate Link Hover", function () {
      expect($("a").css("text-decoration")).toBe("none");
      simulateCssEvent('hover');
      expect($("a").css("text-decoration")).toBe("underline");
      simulateCssEvent('stop');
      expect($("a").css("text-decoration")).toBe("none");
    });
});

答案 2 :(得分:13)

您可以像这样模拟鼠标悬停事件:

<强> HTML

<div id="name">My Name</div>

<强>的JavaScript

var element = document.getElementById('name');
element.addEventListener('mouseover', function() {
  console.log('Event triggered');
});

var event = new MouseEvent('mouseover', {
  'view': window,
  'bubbles': true,
  'cancelable': true
});

element.dispatchEvent(event);

答案 3 :(得分:5)

在这种情况下,我通常做的是使用javascript添加一个类,并将与CSS相同的:hover附加到此类

尝试使用

theElement.addEventListener('onmouseover', 
    function(){ theElement.className += ' hovered' });

或旧版浏览器:

theElement.onmouseover = function(){theElement.className += ' hovered'};

当你离开元素时,你必须使用onmouseout删除“悬停”类...

答案 4 :(得分:2)

您可以使用pseudo:styler,该库可以将CSS伪类应用于元素。

(async () => {
  let styler = new PseudoStyler();
  await styler.loadDocumentStyles();
  document.getElementById('button').addEventListener('click', () => {
    const element = document.getElementById('test')
    styler.toggleStyle(element, ':hover');
  })
})();

免责声明:我是该库的合著者。我们对其进行了设计,以额外支持跨域样式表,尤其是在可能无法控制页面CSS规则的Chrome扩展程序中使用。

答案 5 :(得分:2)

我假设您要在dom操作之后检查CSS,但是一旦将鼠标移回devtools,该事件就不再在该html元素上处于活动状态。您可能希望在devtools中为JavaScript事件提供类似:hover选项的东西。那不存在,但是您可以模拟它。

  1. 打开您的devtools,然后单击它以将其激活。
  2. 在您感兴趣的元素上触发事件。
  3. 在不移动鼠标的情况下,使用ctrl + shift + p打开devtools命令面板,然后使用键盘选择“禁用javascript”。

由于禁用了javascript,因此没有机会再次修改该元素。您可以转到devtools并检查css和html,就好像您正在对其进行悬停,单击或执行其他操作一样。完成后,再次转到命令面板,然后选择“启用javascript”。

答案 6 :(得分:0)

SCSS

.hover {
    @extend :hover;
}