我正在编写一段JavaScript代码,当用户将鼠标悬停在DOM中的某个元素上时,它可以对该元素进行高亮。这应该是一个支持跨浏览器的外部插件,理想情况下,我试图模仿浏览器检查工具的行为。
我不能说没有成功,但我陷入了两难境地,每种方法都有其优缺点。
方式1
我处理mouseover
事件,并简单地向目标元素添加一个边框。当我悬停在另一个元素上时,我只需重置现有的高亮元素即可。以下是相应的代码:
function addHighlight(target) {
target.classList.add('highlighted');
}
function removeHighlight(target) {
target.classList.remove('highlighted');
}
window.addEventListener('mouseover',function(e) {
addHighlight(e.target);
});
window.addEventListener('mouseout',function(e) {
removeHighlight(e.target);
});
该方法的优点
它完全可以正常工作。
该方法的缺点
由于我在现有DOM元素上添加了边框,因此它会重新排列页面上的元素,并且您可以观察到元素的轻微晃动效果。不太美观。
第二种方法
我希望高亮显示是无缝的。也就是说,保留页面的外观,只需在元素上方叠加一个高亮掩码即可。
为了实现这一点,在mouseover
事件中,我动态创建了一个掩码元素,其position
设置为absolute
,并将其坐标设置为目标元素的精确坐标。以下是我的代码:
window.addEventListener('mouseover',function(e) {
applyMask(e.target);
});
function applyMask(target) {
if(document.getElementsByClassName('highlight-wrap').length > 0) {
resizeMask(target);
}else{
createMask(target);
}
}
function resizeMask(target) {
var rect = target.getBoundingClientRect();
var hObj = document.getElementsByClassName('highlight-wrap')[0];
hObj.style.top=rect.top+"px";
hObj.style.width=rect.width+"px";
hObj.style.height=rect.height+"px";
hObj.style.left=rect.left+"px";
// hObj.style.WebkitTransition='top 0.2s';
}
function createMask(target) {
var rect = target.getBoundingClientRect();
var hObj = document.createElement("div");
hObj.className = 'highlight-wrap';
hObj.style.position='absolute';
hObj.style.top=rect.top+"px";
hObj.style.width=rect.width+"px";
hObj.style.height=rect.height+"px";
hObj.style.left=rect.left+"px";
hObj.style.backgroundColor = '#205081';
hObj.style.opacity='0.5';
hObj.style.cursor='default';
//hObj.style.WebkitTransition='top 0.2s';
document.body.appendChild(hObj);
}
function clearMasks() {
var hwrappersLength = document.getElementsByClassName("highlight-wrap").length;
var hwrappers = document.getElementsByClassName("highlight-wrap");
if(hwrappersLength > 0) {
for(var i=0; i<hwrappersLength; i++) {
console.log("Removing existing wrap");
hwrappers[i].remove();
}
}
}
此方法的优点 我认为这更加简洁,不会影响页面,只是在元素上覆盖一层遮罩。
缺点
当用户将鼠标悬停在最顶部的容器(div
)上时,它为该元素创建了遮罩。之后,所有后续的mouseover
事件都被忽略,因为它们是在遮罩上注册的,而不是在实际的底层元素上注册的。我需要找到一个解决这个问题的方法。
有谁能帮我改进第二种方法?或者提出另一种方法?
谢谢, Sriram
outline
代替边框。 - CBroe