css JavaScript -悬停时突出显示元素

lyfkaqu1  于 2023-01-27  发布在  Java
关注(0)|答案(6)|浏览(174)

我正在尝试编写一个JavaScript,当用户将鼠标悬停在DOM中的某个元素上时,它会高亮显示该元素。这应该是一个跨浏览器的外部插件。理想情况下,我正在尝试模仿浏览器检查工具的行为。
我不能说我没有成功,但我坚持两个选择,都有自己的优点和缺点。

    • 方法1**

我处理mouseover事件并简单地给目标元素添加一个边框。当我将鼠标悬停在另一个元素上时,我只重置现有的高亮元素。相同的代码如下:

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

    • 此方法的优点**

它工作得非常好。

    • 此方法的缺点**

当我给现有的DOM元素添加边框时,它在某种程度上重新排列了页面上的元素,您可以观察到元素的轻微移动效果,看起来不太好。

    • 方法2**

我希望高亮显示是无缝的,也就是说,保持页面的外观,只需要在元素的顶部覆盖一个高亮显示遮罩。
为此,我在mouseover事件中动态创建了一个mask元素,将其position设置为absolute,并将其坐标设置为目标元素的精确坐标。

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

    • 这种方法的优点**我觉得这样更优雅,而且不干扰页面,只是在元素顶部覆盖一个掩码。
    • 缺点**

当用户将鼠标悬停在最顶端的容器(div)上时,它会为该元素创建一个掩码。在此之后,所有后续的mouseover事件都会被忽略,因为它们注册在***mask***上,而不是实际的底层元素上。我需要找到一种方法来解决这个问题。
有人能帮助我改进方法2吗?或者建议另一种方法?
谢谢,斯里拉姆

wd2eg0qa

wd2eg0qa1#

你应该在CSS中而不是JS中执行此操作。

.your-class:hover{
    background-color: #205081;
}
b91juud3

b91juud32#

@LouieAlmeda的答案是要走的路
但是如果你想保留蒙版div,你可以:http://jsbin.com/filelavegu/1/edit?html,css,js,output
和你唯一不同是我加了

hObj.style.pointerEvents='none';

在掩模创建时
它使指针事件通过div

esyap4oy

esyap4oy3#

@LouieAlmeda和@jonatjano都是对的,我只是想补充一下,如果你不喜欢重新排列页面上的元素,你可以添加一个border: 1px solid transparent到元素,然后在鼠标悬停/悬停时只改变边框颜色

xzlaal3s

xzlaal3s4#

我通过@jonatjano更改了版本,例如

  • 它考虑了视口滚动
  • 它更紧凑

看它here

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

function updateMask(target) {
    let elements = document.getElementsByClassName("highlight-wrap")
    let hObj
    if (elements.length !== 0) {
        hObj = elements[0]
    } else {
        hObj = document.createElement("div");
        hObj.className = 'highlight-wrap';
        hObj.style.position = 'absolute';
        hObj.style.backgroundColor = '#205081';
        hObj.style.opacity = '0.5';
        hObj.style.cursor = 'default';
        hObj.style.pointerEvents = 'none';
        document.body.appendChild(hObj);
    }
    let rect = target.getBoundingClientRect();
    hObj.style.left = (rect.left + window.scrollX) + "px";
    hObj.style.top = (rect.top + window.scrollY) + "px";
    hObj.style.width = rect.width + "px";
    hObj.style.height = rect.height + "px";

}
qlvxas9a

qlvxas9a5#

您还可以使用:

[attribute = value]:hover {
   css declarations;
}

并在所有应该具有悬停效果的DIV上使用它。

pes8fvy9

pes8fvy96#

这种方法对我很有效,将hover规则应用于所有*元素。

*:hover {
    background-color: #205081 !important;
}

!important确保覆盖在单个HTML节点上设置的背景。请记住CSS的特殊性,即如果悬停的元素上存在与!important类似的规则,浏览器将忽略此CSS规则。
感谢路易,扩展了他的回答。

相关问题