我正在嘗試編寫一個JavaScript,當用戶懸停在DOM中的某個元素上時,它會高亮顯示該元素。這應該是一個跨瀏覽器的外部插件。理想情況下,我試圖模仿瀏覽器檢查工具的行為。
我不能說我沒有成功,但我被困在兩個選項中,這兩個選項各有利弊。
方法1
我處理mouseover事件,并簡單地向目標元素添加一個邊框。當我懸停在另一個元素上時,我只是重置現(xiàn)有的突出顯示的元素。相同的代碼如下:
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);
});
這里是工作示例
贊成這種方法
它絕對好用。
這種方法的缺點
當我向現(xiàn)有的DOM元素添加邊框時,它在某種程度上重新排列了頁面上的元素,您可以觀察到元素的輕微移動效果。看起來不太好。
方法2
我想突出無縫。也就是說,保留頁面的外觀并簡單地在元素上覆蓋一個高亮遮罩。
為此,在mouseover事件中,我動態(tài)地創(chuàng)建了一個mask元素,它的位置被設置為absolute,它的坐標被設置為target元素的精確坐標。以下是我的代碼:
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();
}
}
}
這里是工作示例
贊成這種方法 我覺得這樣更優(yōu)雅,不會擾亂頁面,只是在元素上疊加了一個遮罩。
騙局
當用戶懸停在最頂層的容器(div)上時,它會為該元素創(chuàng)建一個掩碼。之后,所有后續(xù)的mouseover事件都被忽略,因為它們是在掩碼上注冊的,而不是在實際的底層元素上注冊的。 我需要想辦法解決這個問題。
有人能幫我更好的接近2嗎?或者建議另一種方法?
謝謝, 斯里拉姆
你應該用CSS而不是JS來做這件事。使用:懸停選擇器
.your-class:hover{
background-color: #205081;
}
@LouieAlmeda的回答是該走的路
但是,如果你想保持掩碼div你可以做:http://jsbin.com/filelavegu/1/edit? html,css,js,輸出
和你的唯一不同是我加了
hObj.style.pointerEvents='none';
在掩模制作時
它使指針事件通過div
我通過@jonatjano修改了版本,比如
它考慮了視口滾動 它更緊湊 它也可以粘貼到開發(fā)人員控制臺中(小心混淆iframes btw) 看這里
window.addEventListener('mouseover', function (e) {
updateMask(e.target);
});
function updateMask(target) {
let elements = document.getElementsByClassName("highlight-wrap")
let hObj
if (elements.length !== 0) {
hObj = elements[0]
} else {
hObj = document.createElement("div");
hObj.className = 'highlight-wrap';
hObj.style.position = 'absolute';
hObj.style.backgroundColor = '#205081';
hObj.style.opacity = '0.5';
hObj.style.cursor = 'default';
hObj.style.pointerEvents = 'none';
document.body.appendChild(hObj);
}
let rect = target.getBoundingClientRect();
hObj.style.left = (rect.left + window.scrollX) + "px";
hObj.style.top = (rect.top + window.scrollY) + "px";
hObj.style.width = rect.width + "px";
hObj.style.height = rect.height + "px";
}
@LouieAlmeda和@jonatjano都是對的,我只是想補充一點,如果你不喜歡重新排列頁面上的元素,你可以添加一個邊框:1px元素透明,然后在鼠標懸停時改變邊框顏色
您也可以使用:
[attribute = value]:hover {
css declarations;
}
并在所有應該有懸停效果的div上使用它。
這種方法對我有效,將懸停規(guī)則應用于所有*元素。
*:hover {
background-color: #205081 !important;
}
的!重要說明:確保覆蓋在單個HTML節(jié)點上設置的背景。記住CSS的特殊性,也就是說,如果一個相似的規(guī)則與。重要信息出現(xiàn)在懸停的元素上。
感謝路易,擴展他的答案。