Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding Border Implementation for widget on hover like in webflow

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?

enter image description here

like image 748
Chetan Jain Avatar asked Dec 21 '25 07:12

Chetan Jain


1 Answers

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.target instead of document.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>
like image 120
Louys Patrice Bessette Avatar answered Dec 22 '25 22:12

Louys Patrice Bessette



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!