#dom #webflow
#javascript #HTML #dom
Вопрос:
В webflow, когда мы наводим курсор на элемент, он показывает синюю рамку.(Смотрите Видео) Мне интересно узнать, как это реализовано. Я провел свое исследование и мог бы сделать базовое предположение о его реализации.
1 Прослушайте событие наведения курсора мыши на тело 2, затем при обновлении курсора мыши используйте document.getelementfrompoint(), чтобы получить узел элемента в точке, в которой теперь используется абсолютно позиционированный div, добавьте границу в прямой узел наведенного курсора.
Вопрос, правильно ли мое предположение? Существует ли пороговое значение, которое нам нужно проверить, чтобы избежать вызова обработчика перемещения мыши?
Комментарии:
1. Похоже, вы могли бы сделать это в CSS с помощью сочетания
:hover
,::after
, иoutline
. Javascript не требуется.
Ответ №1:
Вот оно… Я не думаю, что есть какие-либо проблемы с запуском событий mousemove. Я вообще не использовал порог (без отмены).
РЕДАКТИРОВАТЬ — Ответ на вопрос OP в комментариях:
Почему вы не использовали
e.target
вместоdocument.elementFromPoint(e.pageX, e.pageY)
?
Хороший вопрос! Сначала я попробовал этот .elementFromPoint()
метод, потому что я не знал об этом до вашего вопроса. И это сработало хорошо. Я думаю, это называется «удача новичка»! лолл! — Теперь я только что попробовал e.target
и увидел скачкообразный эффект, который мотивировал ваш вопрос о пороге.
Причина скачкообразного эффекта проста. В mousemove
сгенерированном объекте события содержится целевой элемент, верно? И это элемент под указателем. Однажды это нужный элемент… И, во-вторых, это добавленный «пограничный div» из нашего скрипта. И это циклически повторяется без остановки.
Теперь, используя document.elementFromPoint(e.pageX, e.pageY)
, это ВСЕГДА нужный элемент, потому что двумя строками выше в скрипте мы удаляем предыдущий «пограничный div», а ЗАТЕМ запрашиваем элемент под указателем.
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>
Комментарии:
1. Спасибо за ваши усилия. Мне любопытно узнать, почему вы не использовали «e.target» вместо «document.elementFromPoint (например,pageX, например, pageY)».
2. Я отредактировал с длинным ответом 😉