3 回答
TA贡献1789条经验 获得超10个赞
现代 JavaScript 使这变得非常容易。您只需要迭代querySelectorAll调用的结果并将侦听器添加到每个孩子。
此外,看起来您的数据是一个 JSON 对象,因此您可能需要使用JSON.parse.
我建议不要每次都销毁和重新创建信息框。只需使用最新信息更新它并根据您当前是否将鼠标悬停在某个区域上来隐藏/显示它。
Array.from(document.querySelectorAll('#regions > *')).forEach(region => {
region.addEventListener('mouseover', e => {
const infobox = document.querySelector('.info_box')
const regionData = JSON.parse(e.target.dataset.region)
infobox.textContent = regionData.region_name
infobox.classList.toggle('hidden', false)
})
region.addEventListener('mousemove', e => {
const infobox = document.querySelector('.info_box')
if (!infobox.classList.contains('hidden')) {
Object.assign(infobox.style, {
top: (e.pageY - 50) + 'px',
left: (e.pageX + 10) + 'px'
})
}
})
region.addEventListener('mouseleave', e => {
const infobox = document.querySelector('.info_box')
infobox.classList.toggle('hidden', true)
})
})
.info_box {
position: absolute;
top: 0;
left: 0;
border: thin solid grey;
background: #FFF;
padding: 0.25em;
}
.info_box.hidden {
display: none;
}
.region {
display: inline-block;
width: 5em;
height: 5em;
line-height: 5em;
text-align: center;
margin: 0.5em;
border: thin solid grey;
}
<div id="regions">
<div class="region" data-region='{"region_name":"A"}'>Section A</div>
<div class="region" data-region='{"region_name":"B"}'>Section B</div>
<div class="region" data-region='{"region_name":"C"}'>Section C</div>
</div>
<div class="info_box hidden">
</div>
TA贡献1802条经验 获得超4个赞
您可以通过实现一个addListeners遍历所有元素并应用各种事件侦听器的函数来简单地做到这一点。
const addListeners = (selector, eventName, listener) => {
Array.from(document.querySelectorAll(selector)).forEach(el => {
typeof eventName === 'string' && listener != null
? el.addEventListener(eventName, listener)
: Object.keys(eventName).forEach(name =>
el.addEventListener(name, eventName[name]))
})
}
addListeners('#regions > *', {
mouseover: e => {
const infobox = document.querySelector('.info_box')
const regionData = JSON.parse(e.target.dataset.region)
infobox.textContent = regionData.region_name
infobox.classList.toggle('hidden', false)
},
mousemove: e => {
const infobox = document.querySelector('.info_box')
if (!infobox.classList.contains('hidden')) {
Object.assign(infobox.style, {
top: (e.pageY - 50) + 'px',
left: (e.pageX + 10) + 'px'
})
}
},
mouseleave: e => {
const infobox = document.querySelector('.info_box')
infobox.classList.toggle('hidden', true)
}
})
.info_box {
position: absolute;
top: 0;
left: 0;
border: thin solid grey;
background: #FFF;
padding: 0.25em;
}
.info_box.hidden {
display: none;
}
.region {
display: inline-block;
width: 5em;
height: 5em;
line-height: 5em;
text-align: center;
margin: 0.5em;
border: thin solid grey;
}
<div id="regions">
<div class="region" data-region='{"region_name":"A"}'>Section A</div>
<div class="region" data-region='{"region_name":"B"}'>Section B</div>
<div class="region" data-region='{"region_name":"C"}'>Section C</div>
</div>
<div class="info_box hidden">
</div>
TA贡献1946条经验 获得超3个赞
//Get the body for Adding and removing the info_box
const body = document.querySelector("body");
//Get All Descendants of #Regions
const elements = document.querySelectorAll("#regions > *");
//Create the info_box Element
const infoBoxElement = document.createElement("div");
//Set the class
infoBoxElement.className = "info_box";
//Iterate over each descendant of Regions
elements.forEach((element) => {
//Let's add MouseOver Event
element.addEventListener("mouseover", (e) => {
//get the "data-"" of the element and Parse it
const regionData = JSON.parse(element.dataset.region);
//Let's reuse the infoBoxElement and Assign the innerHTML
infoBoxElement.innerHTML = regionData.region_name + "<br>";
//Appending the infoBoxElement to the Body
body.append(infoBoxElement);
});
//Let's add MouseMove Event
element.addEventListener("mousemove", (e) => {
const mouseX = e.pageX,
mouseY = e.pageY;
//Get the Infobox HTML element
const infoBox = document.getElementsByClassName("info_box")[0];
//Lets add the css Style
infoBox.style.top = mouseX - 50;
infoBox.style.top = mouseY + 10;
});
//Let's add MouseLeave Event
element.addEventListener("mouseleave", (e) => {
//Get the Infobox HTML element
const infoBox = document.getElementsByClassName("info_box")[0];
//Lets get rid of it
infoBox.remove();
});
});
添加回答
举报