谷歌浏览器扩展:鼠标悬停在哪个div上,就突出显示该div

19

我是新手,正在尝试编写一个Google Chrome扩展程序,它可以在鼠标悬停时突出显示一个 div。如果有一个div位于另一个div内部,并且鼠标悬停在内部的div上,我希望仅突出显示内部的div

我已经使一些示例工作起来了,但是我不确定如何捕获鼠标悬停事件。

3个回答

33
在HTML中,每个鼠标事件都可以访问底层元素。您可以使用JavaScript轻松实现此操作,并且在HTML5中有一个很好的特性叫做classList(感谢来自Chromium的Erik),允许您轻松地添加和删除DOM中的类。
首先,您可以使用Google Chrome的Content Scripts来实现此目的。算法非常简单,您保留对最后访问的DOM的指针,并在访问另一个DIV元素时只需添加/删除类。
在您的manifest.json中,我们将定义对每个页面进行CSS和JS注入的操作。
 ...
  ...
  "content_scripts": [
    {
      "matches": ["http://*/*"],
      "css": ["core.css"],
      "js": ["core.js"],
      "run_at": "document_end",
      "all_frames": true
    }
  ]
  ...
  ...

现在让我们看一下我们的 core.js,我已经包含了一些注释来解释正在发生的事情:
// Unique ID for the className.
var MOUSE_VISITED_CLASSNAME = 'crx_mouse_visited';

// Previous dom, that we want to track, so we can remove the previous styling.
var prevDOM = null;

// Mouse listener for any move event on the current document.
document.addEventListener('mousemove', function (e) {
  var srcElement = e.srcElement;

  // Lets check if our underlying element is a DIV.
  if (srcElement.nodeName == 'DIV') {

    // For NPE checking, we check safely. We need to remove the class name
    // Since we will be styling the new one after.
    if (prevDOM != null) {
      prevDOM.classList.remove(MOUSE_VISITED_CLASSNAME);
    }

    // Add a visited class name to the element. So we can style it.
    srcElement.classList.add(MOUSE_VISITED_CLASSNAME);

    // The current element is now the previous. So we can remove the class
    // during the next iteration.
    prevDOM = srcElement;
  }
}, false);

现在,让我们来看一下简单的core.css样式表:
.crx_mouse_visited {
  background-color: #bcd5eb !important;
  outline: 1px solid #5166bb !important;
}

这就是啦,你会注意到所有的div都会有一个“hovered”状态,类似于在浏览器检查元素时发生的情况。

谢谢Mohamed,你的回答对我非常有帮助。请看下面我做的改进。 - Dudi Boy

9

现在是2018年,这个问题被提出已经过去了7.5年。然而,这个问题仍然很重要,mohamed-mansour 提供的答案是最好的。

但我希望对它进行一些优化,支持https,并为整个Chrome扩展提供完整的文档。

manifest.json

{
    "name": "Mark active image",
    "version": "1.11",
    "description": "Mark image with dashed frame.",
    "permissions": [
        "activeTab",
        "declarativeContent"
    ],
     "content_scripts": [
        {
            "matches": [
                "http://*/*",
                "https://*/*"
            ],
            "css": [
                "imageMarker.css"
            ],
            "js": [
                "imageMarker.js"
            ]
        }
    ],
   "manifest_version": 2
}

imageMarker.js

我在下面的示例中使用虚线轮廓标记页面上的图像(IMG标记),并避免对当前图像进行冗余处理。

// Unique ID for the className.
var MOUSE_VISITED_CLASSNAME = 'crx_mouse_visited';

// Previous dom, that we want to track, so we can remove the previous styling.
var prevDOM = null;

// Mouse listener for any move event on the current document.
document.addEventListener('mousemove', function (e) {
    let srcElement = e.srcElement;

    // Lets check if our underlying element is a IMG.
    if (prevDOM != srcElement && srcElement.nodeName == 'IMG') {

        // For NPE checking, we check safely. We need to remove the class name
        // Since we will be styling the new one after.
        if (prevDOM != null) {
            prevDOM.classList.remove(MOUSE_VISITED_CLASSNAME);
        }

        // Add a visited class name to the element. So we can style it.
        srcElement.classList.add(MOUSE_VISITED_CLASSNAME);

        // The current element is now the previous. So we can remove the class
        // during the next ieration.
        prevDOM = srcElement;
        console.info(srcElement.currentSrc);
        console.dir(srcElement);
    }
}, false);

imageMarker.css

.crx_mouse_visited {
    background-clip: #bcd5eb!important;
    outline: 1px dashed #e9af6e!important;
}

1

@pdknsk 你可以为每个元素设置这个,方法是在 body 的 onload 事件中运行以下代码:

bod= document.body;
walker = document.createTreeWalker(bod,NodeFilter.SHOW_ELEMENT,null,false);
while (walker.nextNode()){
    walker.currentNode.addEventListener("mouseover",on,false);
    walker.currentNode.addEventListener("mouseout",off,false);
}

并像这样修改开和关:

on=function(elem){ oldBG = this.style.backgroundColor;
                   this.style.backgroundColor='#123456';
                   this.addEventListener("mouseout",function(){this.style.backgroundColor= oldBG},false);
}

需要注意的是,这只适用于使用element.style对象设置样式的情况,并且为了使其更加健壮,您需要获取element.style.cssText并处理(使用正则表达式)和修改它。
总的来说,Mohamed Mansour的答案是实现这一目标的最佳方法。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接