我一直在尝试寻找mouseover
在 Chrome 中模拟的代码,但即使“鼠标悬停”侦听器被触发,CSS“悬停”声明也从未设置!
我也试过这样做:
//Called within mouseover listener
theElement.classList.add("hover");
但是似乎没有什么可以将元素更改为其hover
声明中声明的内容。
这可能吗?
我一直在尝试寻找mouseover
在 Chrome 中模拟的代码,但即使“鼠标悬停”侦听器被触发,CSS“悬停”声明也从未设置!
我也试过这样做:
//Called within mouseover listener
theElement.classList.add("hover");
但是似乎没有什么可以将元素更改为其hover
声明中声明的内容。
这可能吗?
你不能。这不是可信事件。
由用户代理生成的事件,无论是作为用户交互的结果,还是作为对 DOM 更改的直接结果,都被用户代理信任,并且具有脚本通过 DocumentEvent.createEvent 生成的事件所没有的特权("Event") 方法,使用 Event.initEvent() 方法修改,或通过 EventTarget.dispatchEvent() 方法调度。可信事件的 isTrusted 属性值为 true,而非可信事件的 isTrusted 属性值为 false。
大多数不受信任的事件不应触发默认操作,但单击或 DOMActivate 事件除外。
您必须添加一个类并在鼠标悬停/鼠标移出事件上手动添加/删除它。
您可以像这样模拟鼠标悬停事件:
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);
我在尝试编写自动化测试时偶然发现了这个问题,以验证给定页面上的特定元素集是否都接收了由 css 为悬停事件设置的一些 css 属性集。
虽然上面的答案完美地解释了为什么不能简单地通过 JS 触发悬停事件然后探测一些感兴趣的 css 值,但它确实回答了最初的问题“我如何在纯 JavaScript 中模拟鼠标悬停来激活 CSS” :徘徊”?” 只是部分。
这不是一个高性能的解决方案。我们仅将它用于自动化测试,其中性能不是问题。
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 文件,将 :hover 替换为空字符串并应用它。这具有应用所有 :hover 样式的效果。现在,您可以通过停止模拟来探索一种咆哮的风格并设置回初始状态。
为什么我们通过从工作表中获取 ,然后执行 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");
});
});
我最常做在这种情况下是使用JavaScript添加类..和将相同CSS
的:hover
这一类
尝试使用
theElement.addEventListener('onmouseover',
function(){ theElement.className += ' hovered' });
或者对于较旧的浏览器:
theElement.onmouseover = function(){theElement.className += ' hovered'};
onmouseout
当您离开元素时,您当然必须使用删除“悬停”类...
您可以使用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');
})
})();
免责声明:我是这个库的合著者。我们将其设计为额外支持跨源样式表,特别是在 Chrome 扩展程序中使用,您可能无法控制页面的 CSS 规则。