Google Chrome Extension: highlight the div that the mouse is hovering over

本秂侑毒 提交于 2019-11-30 10:52:03

问题


I am new to Google Chrome extensions and trying to write an extension that highlights a div on hover. If there is a div inside another div and inner div is hovered, I would like to highlight the internal div only.

I have got some of the samples working but I'm not sure how to catch the hover event.


回答1:


In HTML, every mouse event has access to the underlying element. You can do that easily with JavaScript, and there is a nice feature in HTML5 called classList (thanks to Erik from Chromium) that allows you to add and remove classes from DOM's easily.

First of all, you can achieve this with Google Chrome's Content Scripts. The algorithm is quite straightforward, you keep a pointer to the last visited DOM, and you just add/remove class's when you visit another DIV element.

Within your manifest.json We will define the CSS and JS injections to every page we see.

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

Now lets look into our core.js, I have included some comments to explain what is going on:

// 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);

Now, lets look at the simple core.css for the styles:

.crx_mouse_visited {
  background-color: #bcd5eb !important;
  outline: 1px solid #5166bb !important;
}

Thats it, you will notice that all your divs will have a "hovered" state, similar on what happens when you visit your browser inspector when inspecting elements.




回答2:


Now it is 2018, and 7.5 years past since this question was asked. Yet the question is still relevant, and the answer provided by mohamed-mansour is the best.

Yet I wish to optimize it a bit, modernize with support for https, and provide full documentation to the whole Chrome extension.

mannifest.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

In my example bellow I am marking images (IMG tag) in the page with dashed outline. And avoid redundant processing on the current image.

// 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 What you can do to set this for every element is, for the onload event of the body, run this code:

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);
}

and modify on and off like this:

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

The thing to notice is that, this will only work if the styling is set using the element.style object, and in order to make it more robust you will need to get the element.style.cssText and process (using regex) and modify it.

All in all, Mohamed Mansour's Answer is the best way to achieve this.



来源:https://stackoverflow.com/questions/4445102/google-chrome-extension-highlight-the-div-that-the-mouse-is-hovering-over

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!