In webflow when we hover over an element it shows a blue border.(See Video) I am interested in knowing how it is implemented. I have done my research and could make a basic guess of its implementation.
1 Listen to mouseover event on the body 2 then on mouseover update use document.getelementfrompoint() to get the element node at the point Now using an absolutely positioned div add a border at the hovered node rect.
The question is my guess correct? Is there a threshold amount that we need to check to avoid calling mousemove handler?

Here it is... I don't think there is any issue about the mousemove events firering a lot. I used no threshold at all (no debouncing).
EDIT - Answer to OP question in comments:
Why didn't you use
e.targetinstead ofdocument.elementFromPoint(e.pageX, e.pageY)?
Good question! I tried the .elementFromPoint() method first because I didn't know about it before your question. And it worked well. It is called "beginner's luck", I think! loll! -- Now I just tried with e.target and saw the jumpy effect that motivated your question about a threshold.
The reason for the jumpy effect is simple. On mousemove the generated event object contains the target element, right? And that is the element under the pointer. Once, it is the wanted element... And second, it is the added "border div" from our script. And it cycles like this non-stop.
Now using document.elementFromPoint(e.pageX, e.pageY), it ALWAYS is the wanted element because two lines above in the script, we are removing the previous "border div" and THEN querying for the element under the pointer.
function showElement(e) {
// If there is already an appended div, remove it
let prev = document.querySelector(".border")
if(prev){
prev.remove()
}
// Get the element. If there's none, stop here to avoid errors
let elem = document.elementFromPoint(e.pageX, e.pageY)
if(!elem){return}
let elemTagname = elem.tagName.toLowerCase()
let elemRect = elem.getBoundingClientRect()
// Create a div to show the elem borders
let border = document.createElement("div")
border.classList.add("border")
border.style.top = elemRect.top + "px"
border.style.left = elemRect.left + "px"
border.style.width = elemRect.width + "px"
border.style.height = elemRect.height + "px"
// Create a span to show the tag name
let tag = document.createElement("span")
tag.classList.add("tag")
tag.innerText = elemTagname
// Append!
border.append(tag)
document.documentElement.append(border)
}
// Mousemove handler
document.documentElement.addEventListener("mousemove", showElement)
div{
height: 300px;
}
.border{
border: 1px solid blue;
position: absolute;
top: 0;
left: 0;
width: 0;
height: 0;
}
.tag{
background: lightgrey;
color: blue;
font-family: arial;
margin-left: 0.3em;
padding: 0 0.3em;
}
<div>
<h1>Header</h1>
<p>Paragraph</p>
<ul>
<li>List item</li>
<li>List item</li>
<li>List item</li>
</ul>
</div>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With