admin管理员组文章数量:1198811
I'm trying to write a JavaScript which will highlight an element in the DOM when the user hovers over it. This is supposed to be a cross-browser external plug-in. Ideally, i'm trying to mimic the behaviour of the browser inspector tools.
I can't say I have no success, but I am stuck with two options, both with its own pros and cons.
Approach 1
I handle the mouseover
event and simply add a border to the target element. When I hover on another element, I just reset the existing highlighted elements. The code for the same is below:
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);
});
Working Example here
Pros with this Approach
It works absolutely fine.
Cons with this approach
As I'm adding a border to existing DOM elements, it sort of re-arranges the elements on the page, and you can observe a slight shuffling effect of the elements. Doesn't look great.
Approach 2
I wanted the highlighting to be seamless. That is, preserving the look of the page and simply overlaying a highlight mask on top of the element.
TO do this, in the mouseover
event, I dynamically created a mask element, whose position
is set to absolute
and its co-ordinates set to the exact co-ordinates of the target element. Below is my code:
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();
}
}
}
Working example here
Pros with this approach I feel this is more elegant, and doesn't disturb the page, just overlays a mask on top of elements.
Cons
When the user hovers over the top most container (div
), it creates a mask for that element. After that, all the subsequent mouseover
events are ignored, as they are registered on the mask, and not on the actual underlying elements.
I need to figure out a way around this.
Can anyone help me better Approach 2? Or suggest another approach?
Thanks, Sriram
I'm trying to write a JavaScript which will highlight an element in the DOM when the user hovers over it. This is supposed to be a cross-browser external plug-in. Ideally, i'm trying to mimic the behaviour of the browser inspector tools.
I can't say I have no success, but I am stuck with two options, both with its own pros and cons.
Approach 1
I handle the mouseover
event and simply add a border to the target element. When I hover on another element, I just reset the existing highlighted elements. The code for the same is below:
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);
});
Working Example here
Pros with this Approach
It works absolutely fine.
Cons with this approach
As I'm adding a border to existing DOM elements, it sort of re-arranges the elements on the page, and you can observe a slight shuffling effect of the elements. Doesn't look great.
Approach 2
I wanted the highlighting to be seamless. That is, preserving the look of the page and simply overlaying a highlight mask on top of the element.
TO do this, in the mouseover
event, I dynamically created a mask element, whose position
is set to absolute
and its co-ordinates set to the exact co-ordinates of the target element. Below is my code:
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();
}
}
}
Working example here
Pros with this approach I feel this is more elegant, and doesn't disturb the page, just overlays a mask on top of elements.
Cons
When the user hovers over the top most container (div
), it creates a mask for that element. After that, all the subsequent mouseover
events are ignored, as they are registered on the mask, and not on the actual underlying elements.
I need to figure out a way around this.
Can anyone help me better Approach 2? Or suggest another approach?
Thanks, Sriram
Share Improve this question asked Aug 20, 2018 at 7:21 Sriram SridharanSriram Sridharan 7402 gold badges22 silver badges47 bronze badges 1 |6 Answers
Reset to default 11You should do this in CSS and not in JS. Use the :hover
selector
.your-class:hover{
background-color: #205081;
}
@LouieAlmeda's answer is the way to go
But if you want to keep the mask div you can do : http://jsbin.com/filelavegu/1/edit?html,css,js,output
the only difference with your is that I added
hObj.style.pointerEvents='none';
at the mask creation
It makes the pointerevent pass through the div
I changed the version by @jonatjano, such as
- it takes in account the viewport scrolling
- it is more compact
- it works also pasted in the developer console (beware of confounding iframes btw)
Working example here
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 and @jonatjano are both right, i just want to add that if you don't like the re-arranges the elements on the page, you can add a border: 1px solid transparent
to elements and then on mouse-over/hover just change the border-color
You can also use:
[attribute = value]:hover {
css declarations;
}
and use it on all divs which should have hover effect.
This approach worked for me, applying the hover
rule to all *
elements.
*:hover {
background-color: #205081 !important;
}
The !important
ensures overwriting backgrounds set on individual HTML nodes. Keep CSS specificity mind, that is that the browser ignores this CSS rule if a similar rule with !important
is present on the hovered element.
Thanks to Louie, extending his answer.
本文标签: htmlJavaScriptHighlight an element on HoverStack Overflow
版权声明:本文标题:html - JavaScript - Highlight an element on Hover - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1738555942a2098288.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
outline
instead of a border. – C3roe Commented Aug 20, 2018 at 7:27