【问题标题】:Google Chrome Extension: highlight the div that the mouse is hovering over谷歌浏览器扩展:突出显示鼠标悬停的 div
【发布时间】:2010-12-14 22:51:51
【问题描述】:

我是 Google Chrome 扩展程序的新手,正在尝试编写一个在悬停时突出显示 div 的扩展程序。如果在另一个div 内部有一个div 并且内部div 悬停,我想仅突出显示内部div

我已经得到了一些示例,但我不确定如何捕捉悬停事件。

【问题讨论】:

    标签: google-chrome-extension onhover


    【解决方案1】:

    在 HTML 中,每个鼠标事件都可以访问底层元素。您可以使用 JavaScript 轻松地做到这一点,HTML5 中有一个很棒的功能称为classList(感谢 Chromium 的 Erik),它允许您轻松地在 DOM 中添加和删除类。

    首先,您可以使用谷歌浏览器的Content Scripts 来实现这一点。该算法非常简单,您保留一个指向上次访问的 DOM 的指针,并且您只需在访问另一个 DIV 元素时添加/删除类。

    在您的 ma​​nifest.json 中,我们将为我们看到的每个页面定义 CSS 和 JS 注入。

     ...
      ...
      "content_scripts": [
        {
          "matches": ["http://*/*"],
          "css": ["core.css"],
          "js": ["core.js"],
          "run_at": "document_end",
          "all_frames": true
        }
      ]
      ...
      ...
    

    现在让我们看看我们的 core.js,我已经包含了一些 cmets 来解释发生了什么:

    // 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 都将处于“悬停”状态,类似于您在检查元素时访问浏览器检查器时发生的情况。

    【讨论】:

    • 好答案,只有我会将border 替换为outline,添加边框会移动元素。可能还需要 css 上的 !important
    • 谢谢军士!编辑帖子以反映您的 cmets :)
    • 感谢 Mohamed,您的回答帮助我分配。请在下面查看我的改进。
    【解决方案2】:

    现在是 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;
    }
    

    【讨论】:

      【解决方案3】:

      @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 的回答是实现这一目标的最佳方式。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-10-08
        • 2012-04-21
        • 2012-12-15
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多