Triggering Hover css pseudo class programmatically
css, javascript
Solution
No, you cannot use JavaScript to directly make the element register as hovered such that the `:hover` CSS would trigger without the mouse being over the element in question.
The closest you can get is to use JavaScript to look up the CSS rules that would be applied during a `:hover` and then manually apply them, as demonstrated in this gist (duplicated below for posterity's sake):
// Find all css properties for the :hover you want
var applyHoverStyle = function() {
var div = document.getElementsByTagName("div")[0];
var i,j, sel = /div:hover/, aProperties = [];
for(i = 0; i < document.styleSheets.length; ++i){
// console.log(document.styleSheets[i]);
if(document.styleSheets[i]. cssRules !== null) {
for(j = 0; j < document.styleSheets[i].cssRules.length; ++j){
if(sel.test(document.styleSheets[i].cssRules[j].selectorText)){
aProperties.push(document.styleSheets[i].cssRules[j].style.cssText);
// console.log(document.styleSheets[i].cssRules[j].selectorText, document.styleSheets[i].cssRules[j].style.cssText);
}
}
}
}
//console.log(aProperties);
div.style.cssText = aProperties.join(' ');
};
Problem
I need to trigger the hover pseudo class programmatically (if possible with bubbling, or i will be forced to call the change to all elements parents too). I don't have the control of the html page, so i can't change the css from :hover to .hover in order to update the class of the HTMLElement to the .hover one. Is that possible? Please NO JQUERY. I can't use JQuery in my project. Thank you in advance. UPDATE i've created a sort of proxy for CSS loading, so now before a css is loaded it passes in my "proxy" that changes the rules from :hover to .hoverclass. Well, now the hover effects works pretty well, but i have some serious performance issue due to the bubbling simulation of the hover. Here is some code: ``` var actualHoveredElements = new Array(); var hoverAddedCount = 0; var maxHoveredElems = 5; function changeHover(newElement, oldElement){ var oldHoveredElements = actualHoveredElements.slice(); var remainingElements = setHoverForParentsOfElement(newElement, oldHoveredElements); for(var i = 0; i < remainingElements.length; i++){ var notHoveredElement = remainingElements[i]; var actualIndex = actualHoveredElements.indexOf(notHoveredElement); if(actualIndex > -1){ actualHoveredElements.splice(actualIndex, 1); } notHoveredElement.classList.remove("hoverclass"); } hoverAddedCount = 0; changeHoverTimeout = null; } function setHoverForParentsOfElement(element, oldHoveredElements){ var index = -1; if(oldHoveredElements != "undefined" && oldHoveredElements.length > 0) index = oldHoveredElements.indexOf(element); if(index > -1){ oldHoveredElements.splice(index, 1); } else { actualHoveredElements.push(element); element.classList.add("hoverclass"); } if(element.tagName != "BODY" && element.tagName != "HTML"){ if(hoverAddedCount < maxHoveredElems-1){ hoverAddedCount ++; oldHoveredElements = setHoverForParentsOfElement(element.parentNode, oldHoveredElements); } } return oldHoveredElements; } ``` As you can see, i've also tried to limit the number of hover bubbling to N, but the performance issue is still existing.