Расширение Google Chrome: выделите элемент div, над которым наведена мышь - PullRequest
11 голосов
/ 15 декабря 2010

Я новичок в расширениях Google Chrome и пытаюсь написать расширение, которое выделяет div при наведении курсора. Если внутри другого div есть div, а внутри находится div, я бы хотел выделить только внутреннее div.

У меня есть некоторые сэмплы, но я не уверен, как поймать событие при наведении.

Ответы [ 3 ]

22 голосов
/ 15 декабря 2010

В HTML каждое событие мыши имеет доступ к базовому элементу. Это легко сделать с помощью JavaScript, и в HTML5 есть замечательная функция classList (спасибо Эрику из Chromium), которая позволяет легко добавлять и удалять классы из DOM.

Прежде всего, вы можете добиться этого с помощью скриптов содержания Google Chrome . Алгоритм довольно прост: вы сохраняете указатель на последний посещенный 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'ы будут в состоянии "зависания", аналогично тому, что происходит при посещении инспектора браузера при проверке элементов.

2 голосов
/ 30 июня 2018

Сейчас 2018 год, и прошло 7,5 лет с тех пор, как был задан этот вопрос. Тем не менее, вопрос все еще актуален, и ответ, предоставленный Мохамед-Мансур , является лучшим.

И все же я хочу немного его оптимизировать, модернизировать с поддержкой https и предоставить полную документацию для всего расширения Chrome.

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

В моем примере ниже я отмечаю изображения (тег 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 голос
/ 18 июля 2011

@ pdknsk То, что вы можете сделать, чтобы установить это для каждого элемента, для события 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 и обработать (используя регулярное выражение) и измените его.

В общем, ответ Мохамеда Мансура - лучший способ добиться этого.

...