Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaScript - Highlight an element on Hover

I'm trying to write a JavaScript which will highlight an element in the DOM when the user hovers over it. This is supposed to be a cross-browser external plug-in. Ideally, i'm trying to mimic the behaviour of the browser inspector tools.

I can't say I have no success, but I am stuck with two options, both with its own pros and cons.

Approach 1

I handle the mouseover event and simply add a border to the target element. When I hover on another element, I just reset the existing highlighted elements. The code for the same is below:

function addHighlight(target) {
    target.classList.add('highlighted');
}

function removeHighlight(target) {
    target.classList.remove('highlighted');
}

window.addEventListener('mouseover',function(e) {
    addHighlight(e.target);
});

window.addEventListener('mouseout',function(e) {
    removeHighlight(e.target);
});

Working Example here

Pros with this Approach

It works absolutely fine.

Cons with this approach

As I'm adding a border to existing DOM elements, it sort of re-arranges the elements on the page, and you can observe a slight shuffling effect of the elements. Doesn't look great.

Approach 2

I wanted the highlighting to be seamless. That is, preserving the look of the page and simply overlaying a highlight mask on top of the element.

TO do this, in the mouseover event, I dynamically created a mask element, whose position is set to absolute and its co-ordinates set to the exact co-ordinates of the target element. Below is my code:

window.addEventListener('mouseover',function(e) {
    applyMask(e.target);
});

function applyMask(target) {
    if(document.getElementsByClassName('highlight-wrap').length > 0) {
        resizeMask(target);
    }else{
        createMask(target);
    }
}

function resizeMask(target) {
    var rect = target.getBoundingClientRect();
    var hObj = document.getElementsByClassName('highlight-wrap')[0];
    hObj.style.top=rect.top+"px";
    hObj.style.width=rect.width+"px";
    hObj.style.height=rect.height+"px";
    hObj.style.left=rect.left+"px";
   // hObj.style.WebkitTransition='top 0.2s';
}

function createMask(target) {
    var rect = target.getBoundingClientRect();
    var hObj = document.createElement("div");
    hObj.className = 'highlight-wrap';
    hObj.style.position='absolute';
    hObj.style.top=rect.top+"px";
    hObj.style.width=rect.width+"px";
    hObj.style.height=rect.height+"px";
    hObj.style.left=rect.left+"px";
    hObj.style.backgroundColor = '#205081';
    hObj.style.opacity='0.5';
    hObj.style.cursor='default';
    //hObj.style.WebkitTransition='top 0.2s';
    document.body.appendChild(hObj);
}

function clearMasks() {
    var hwrappersLength = document.getElementsByClassName("highlight-wrap").length;
    var hwrappers = document.getElementsByClassName("highlight-wrap");
    if(hwrappersLength > 0) {
        for(var i=0; i<hwrappersLength; i++) {
            console.log("Removing existing wrap");
            hwrappers[i].remove();
        }
    }
}

Working example here

Pros with this approach I feel this is more elegant, and doesn't disturb the page, just overlays a mask on top of elements.

Cons

When the user hovers over the top most container (div), it creates a mask for that element. After that, all the subsequent mouseover events are ignored, as they are registered on the mask, and not on the actual underlying elements. I need to figure out a way around this.

Can anyone help me better Approach 2? Or suggest another approach?

Thanks, Sriram

like image 673
Sriram Sridharan Avatar asked Dec 14 '22 15:12

Sriram Sridharan


1 Answers

You should do this in CSS and not in JS. Use the :hover selector

.your-class:hover{
    background-color: #205081;
}
like image 118
Louie Almeda Avatar answered Dec 17 '22 22:12

Louie Almeda