我一直試圖在Chrome中找到模擬mouseover的代碼,但即使“mouseover”監聽器被觸發,CSS“hover”聲明也從未設置!
我還試著做:
//Called within mouseover listener
theElement.classList.add("hover");
但是似乎沒有什么能改變元素在懸停聲明中的聲明。
這可能嗎?
你不能。這不是一個可信的事件。
用戶代理生成的事件,無論是作為用戶交互的結果,還是作為對DOM進行更改的直接結果,都受到用戶代理的信任,而用戶代理所擁有的特權是腳本通過document event . create event(& quot;事件& quot)方法,使用Event.initEvent()方法修改,或通過EventTarget.dispatchEvent()方法調度。可信事件的isTrusted屬性值為true,而不可信事件的isTrusted屬性值為false。
大多數不受信任的事件不應該觸發默認操作,click或DOMActivate事件除外。
您必須添加一個類,并在mouseover/mouseout事件中手動添加/移除該類。
您可以像這樣模擬鼠標懸停事件:
超文本標記語言
<div id="name">My Name</div>
Java Script語言
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值,但它確實回答了最初的問題& quot我如何用純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文件,用空字符串替換:hover并應用它。這樣做的效果是,所有:懸停樣式都被應用。現在,人們可以探測一個howered風格,并通過停止模擬設置回初始狀態。
為什么我們要對整個文檔應用懸停效果,而不是只對感興趣的元素應用,方法是從工作表中獲取,然后執行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添加一個類..并將與:hover相同的CSS附加到該類
嘗試使用
theElement.addEventListener('onmouseover',
function(){ theElement.className += ' hovered' });
或者對于較舊的瀏覽器:
theElement.onmouseover = function(){theElement.className += ' hovered'};
當然,您必須使用onmouseout來刪除& quot徘徊& quot當您離開元素時初始化...
您可以使用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擴展中使用,在Chrome擴展中,您可能缺乏對頁面CSS規則的控制。
我假設您想在dom操作后檢查CSS,但是一旦您將鼠標移回devtools,該html元素上的事件就不再活動了。您可能希望在devtools中為您的javascript事件提供類似:hover的選項。那是不存在的,但是你可以模擬一下。
打開您的devtools并單擊它以激活它。 在您感興趣的元素上觸發事件。 不用移動鼠標,用ctrl + shift + p打開devtools命令面板,用鍵盤選擇“禁用javascript”。 由于javascript被禁用,它沒有機會再次修改元素。你可以使用devtools檢查css和html,就像你在上面懸停、點擊或做其他事情一樣。完成后,再次進入命令面板,選擇“啟用javascript”。
我想提一個僅使用css的不同方法來解決這個問題,但我在這里假設:當其中一個父標簽發生變化時,將觸發懸停,如下所示:
function btn_activated(){
const button = document.querySelector('button.btn');
if(button.classList.contains('active')){
button.classList.remove('active');
}else{
button.classList.add('active');
}
}
.btn{
width: 100px;
height: 30px;
}
.btn:hover > span.visually-hidden,
.active> span.visually-hidden{
display: inline;
}
.visually-hidden{
display: none;
}
<button class="btn" onClick="btn_activated()">
<span class="visually-hidden">
hovered
</span>
</button>