Background
I stumbled upon this question while trying to write automated tests, to verify, that a certain set of elements on a given page all receive have the some set of css properties set by the css for on hover events.
While the above answer perfectly explains, why it is not possible to simply trigger the hover event by JS and then probe some css value of interest, it does answer the initial question "How do I simulate a mouseover in pure JavaScript that activates the CSS “:hover”?" only partly.
Disclaimer
This is not a performant solution. We use it only for automated testing, where performance is not a concern.
Solution
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();
}
}
Explanation
generateEvent reads all css files, , replaces :hover with an empty string and applies it. This has the effect, that all :hover styles are applied. Now one can probe for a howered style and set back to initial state by stopping the Simulation.
Why do we apply the hover effect for the whole document and not just for the element of interest by getting the from the sheets and then perform a element.css(...)?
Done as that, the style would be applied inline, this would override other styles, which might not be overriden by the original css hover-style.
How would I now simulate the hover for a single element?
This is not performant, so better don't. If you must, you could check with the element.is(selectorOfInterest) if the style applies for your element and only use those styles.
Example
In Jasmine you can e.g. now perform:
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");
});
});
:hover
state on an element. – Jeannajeanne