【发布时间】:2010-12-14 22:51:51
【问题描述】:
我是 Google Chrome 扩展程序的新手,正在尝试编写一个在悬停时突出显示 div 的扩展程序。如果在另一个div 内部有一个div 并且内部div 悬停,我想仅突出显示内部div。
我已经得到了一些示例,但我不确定如何捕捉悬停事件。
【问题讨论】:
标签: google-chrome-extension onhover
我是 Google Chrome 扩展程序的新手,正在尝试编写一个在悬停时突出显示 div 的扩展程序。如果在另一个div 内部有一个div 并且内部div 悬停,我想仅突出显示内部div。
我已经得到了一些示例,但我不确定如何捕捉悬停事件。
【问题讨论】:
标签: google-chrome-extension onhover
在 HTML 中,每个鼠标事件都可以访问底层元素。您可以使用 JavaScript 轻松地做到这一点,HTML5 中有一个很棒的功能称为classList(感谢 Chromium 的 Erik),它允许您轻松地在 DOM 中添加和删除类。
首先,您可以使用谷歌浏览器的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,我已经包含了一些 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。
现在是 2018 年,距离提出这个问题已有 7.5 年了。 然而这个问题仍然是相关的,mohamed-mansour 提供的答案是最好的。
但我希望对其进行一些优化,通过对 https 的支持进行现代化改造,并为整个 Chrome 扩展提供完整的文档。
{
"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
}
在下面的示例中,我在页面中使用虚线轮廓标记图像(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);
.crx_mouse_visited {
background-clip: #bcd5eb!important;
outline: 1px dashed #e9af6e!important;
}
【讨论】:
@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 的回答是实现这一目标的最佳方式。
【讨论】: