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();
});
});
添加回答
舉報