我写的JavaScript徘徊在两个元素之间。但它比我想象的要长得多。
这段代码有很多共同点,比如样式,所以我认为它可以改进得更短、更易于理解。但是,我不知道如何改善这一点。
// It's very long and has duplicate processing.
document.querySelectorAll(".btn").forEach(btn => {
btn.addEventListener("mouseenter", event => {
let index = [
...document.querySelector(".wrap_square > ul.square_list").children
].findIndex(c => c == event.target.parentNode);
if (event.target.tagName === "A") {
index = [...document.querySelectorAll(".wrap_list > ul.list_list")]
.map(e => [...e.children])
.flat()
.findIndex(c => c == event.target.parentNode);
}
if (event.target.tagName === "A") {
event.target.style.color = "#E91E63";
document.querySelectorAll(".square_list li > .btn")[
index
].style.backgroundColor =
"rgba(233, 30, 99, 0.71)";
} else {
event.target.style.backgroundColor = "rgba(233, 30, 99, 0.71)";
document.querySelectorAll(".list_list li > a")[index].style.color =
"#E91E63";
}
});
btn.addEventListener("mouseleave", event => {
let index = [
...document.querySelector(".wrap_square > ul.square_list").children
].findIndex(c => c == event.target.parentNode);
if (event.target.tagName === "A") {
index = [...document.querySelectorAll(".wrap_list > ul.list_list")]
.map(e => [...e.children])
.flat()
.findIndex(c => c == event.target.parentNode);
}
if (event.target.tagName === "A") {
event.target.style.color = "";
document.querySelectorAll(".square_list li > .btn")[
index
].style.backgroundColor =
"";
} else {
event.target.style.backgroundColor = "";
document.querySelectorAll(".list_list li > a")[index].style.color = "";
}
});
});
.area_map {
height: 20vh;
}
.btn {
width: 6vw;
height: 2vh;
border: 1px solid;
}
li+li {
margin-top: 2px;
}
<div class="main">
<p class="title">Hover square or link</p>
<div class="wrapper">
<div class="wrap_square">
<ul class="square_list">
<li>
<div class="btn"></div>
</li>
<li>
<div class="btn"></div>
</li>
<li>
<div class="btn"></div>
</li>
<li>
<div class="btn"></div>
</li>
<li>
<div class="btn"></div>
</li>
<li>
<div class="btn"></div>
</li>
<li>
<div class="btn"></div>
</li>
<li>
<div class="btn"></div>
</li>
</ul>
</div>
<div class="wrap_list">
<ul class="list_list left">
<li><a href="#" class="btn">one</a></li>
<li><a href="#" class="btn">two</a></li>
<li><a href="#" class="btn">three</a></li>
<li><a href="#" class="btn">four</a></li>
</ul>
<ul class="list_list right">
<li><a href="#" class="btn">five</a></li>
<li><a href="#" class="btn">six</a></li>
<li><a href="#" class="btn">seven</a></li>
<li><a href="#" class="btn">eight</a></li>
</ul>
</div>
</div>
如何消除这些公共区域并使代码更易于阅读?
我会把它写成:
const $ = selector => [...document.querySelectorAll(selector)];
const on = (target, type, handler) => target.forEach(it => it.addEventListener(type, handler));
const highlight = button => {
for(const button of buttons)
button.style.color = button === target ? "#E91E63" : "";
};
const buttons = $(".square_list > .btn"), links = $(".wrap_list > .btn");
on(buttons, "mouseenter", ({ target }) => {
highlight(target);
});
on(links, "click", ({ target }) => {
const buttonTarget = buttons[ links.indexOf(target) ];
highlight(buttonTarget);
});