当存在要分配的属性名称和值不同的常见处理时,其智能分组方法



我写的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);
   });

最新更新