Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Triggering Hover css pseudo class programmatically

Tags:

javascript

css

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.

like image 929
Giuseppe Lanza Avatar asked Feb 10 '14 08:02

Giuseppe Lanza


People also ask

How do you hover pseudo elements in CSS?

The :hover CSS pseudo-class matches when the user interacts with an element with a pointing device, but does not necessarily activate it. It is generally triggered when the user hovers over an element with the cursor (mouse pointer).

Can you hover pseudo elements?

To clarify, you CAN NOT give :hover to a pseudo element. There's no such thing as ::after:hover in CSS as of 2018.

Is hover a pseudo selector?

For example, the pseudo-class :hover can be used to select a button when a user's pointer hovers over the button and this selected button can then be styled.

Is hover a pseudo?

The :hover is pseudo-class and :before & :after are pseudo-elements. In CSS, pseudo-elements are written after pseudo-class.


1 Answers

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(' ');
};
like image 189
Woodrow Barlow Avatar answered Sep 28 '22 04:09

Woodrow Barlow