-1

document.querySelectorAll('.selector').forEach((item) => {
  item.addEventListener("click", (event) => {
    document.querySelectorAll('.dropdown').classList.add("active");
  });
});
.body-ct .selector{display:inline-block;width:200px;text-align:center;border:1px solid navy;border-radius:4px;}
.body-ct .selector:hover{cursor:pointer;}
.body-ct .selector h4{padding:5px 0;}
.body-ct .selector {position:relative;}
.body-ct .selector .dropdown{display:none;position:absolute;top:55px;z-index:2;width:200px;border:3px solid red;background-color:#FFF;}
.body-ct .selector .dropdown.active{display:block;}
.body-ct .selector .dropdown ul{list-style-type:none;text-align:left;background-color:#FFF;}
.body-ct .selector .dropdown ul li{background-color:#FFF;}
.body-ct .selector .dropdown ul li:hover{font-weight:700;}
<section class="body-ct">
  <div class="container">
    <div class="row">
      <div class="col-12 sel-ct">
        <div class="story-type-sel selector">
          <h4>Story Type</h4>
          <div class="dropdown story-selector">
            <ul>
              <li data-type="article">Article</li>
              <li data-type="pr">Press Release</li>
              <li data-type="analyst">Analyst Report</li>
            </ul>
          </div>
        </div>
        <div class="year-sel selector">
          <h4>Year</h4>
          <div class="dropdown year-selector">
            <ul>
              <li data-year="2021">2021</li>
              <li data-year="2020">2020</li>
              <li data-year="2019">2019</li>
              <li data-year="2018">2018</li>
            </ul>
          </div>
        </div>
      </div>  
    </div>
  </div>
</section>

我无法dropdown从我的事件侦听器中引用该类。我认为这与使用.target或有关.currentTarget,但我不知道如何将它放在一起。

当用户单击带有 的元素时.selector,应通过添加一个.active类来显示一个下拉菜单。

document.querySelectorAll(".selector").forEach((item) => {
  item.addEventListener("click", (event) => {
    document.querySelector(".dropdown").classList.add("active");
  });
});

这是 jQuery 中的相同内容,但我不想使用 jQuery。

$(".selector").on("click", function () {
  $(this).find(".dropdown").addClass("active");
});
4

3 回答 3

1

一个幼稚/基本的事件和状态/外观处理方法可能看起来像下一个......

function deactivateDropdown(elm) {
  elm.classList.remove('active');
}
function activateDropdown(elm) {
  elm.classList.add('active');
}

function deactivateAnyDropdown() {
  document
    .querySelectorAll('.dropdown')
    .forEach(deactivateDropdown);
}
function handleSelectorClick(evt) {
  evt.stopPropagation();

  deactivateAnyDropdown();
  activateDropdown(
    evt
      .currentTarget
      .querySelector('.dropdown')
  );
}

function init() {
  document
    .body
    .addEventListener('click', deactivateAnyDropdown)

  document
    .querySelectorAll('.selector')
    .forEach(item =>
      item.addEventListener('click', handleSelectorClick)
    );
}
init();
.body-ct .selector{display:inline-block;width:200px;text-align:center;border:1px solid navy;border-radius:4px;}
.body-ct .selector:hover{cursor:pointer;}
.body-ct .selector h4{padding:5px 0;}
.body-ct .selector {position:relative;}
.body-ct .selector .dropdown{display:none;position:absolute;top:55px;z-index:2;width:200px;border:3px solid red;background-color:#FFF;}
.body-ct .selector .dropdown.active{display:block;}
.body-ct .selector .dropdown ul{list-style-type:none;text-align:left;background-color:#FFF;}
.body-ct .selector .dropdown ul li{background-color:#FFF;}
.body-ct .selector .dropdown ul li:hover{font-weight:700;}
<section class="body-ct">
  <div class="container">
    <div class="row">
      <div class="col-12 sel-ct">
        <div class="story-type-sel selector">
          <h4>Story Type</h4>
          <div class="dropdown story-selector">
            <ul>
              <li data-type="article">Article</li>
              <li data-type="pr">Press Release</li>
              <li data-type="analyst">Analyst Report</li>
            </ul>
          </div>
        </div>
        <div class="year-sel selector">
          <h4>Year</h4>
          <div class="dropdown year-selector">
            <ul>
              <li data-year="2021">2021</li>
              <li data-year="2020">2020</li>
              <li data-year="2019">2019</li>
              <li data-year="2018">2018</li>
            </ul>
          </div>
        </div>
      </div>  
    </div>
  </div>
</section>

...它为停用当前未使用/单击的下拉菜单提供了基本支持。

但是,上述行为当然远非理想。因此,更高级的方法将只关注一个元素,在这种情况下,它是由 OP 分类为的下拉菜单的触发器.selector

人们希望active-class 也成为该元素的一部分,而不是adding 和/或removeing 这个类,而是希望toggle它。

原因之一是需要相应地更改相关切换行为的 css 选择器。

上面的示例代码然后更改为以下...

function deactivateDropdown(elm) {
  elm.classList.remove('active');
}
function toggleDropdown(elm) {
  elm.classList.toggle('active');
}

function deactivateAnyNonActiveDropdown(evt) {
  const { currentTarget, target } = evt;
  Array
    .from(
      document.querySelectorAll('.selector')
    )
    .filter(elm =>
      elm !== currentTarget ||
      elm
        .querySelector('.dropdown')
        .contains(target)
    )
    .forEach(deactivateDropdown);
}
function handleSelectorClick(evt) {
  evt.stopPropagation();

  deactivateAnyNonActiveDropdown(evt);
  toggleDropdown(evt.currentTarget);
}

function init() {
  document
    .body
    .addEventListener('click', deactivateAnyNonActiveDropdown)

  document
    .querySelectorAll('.selector')
    .forEach(item =>
      item.addEventListener('click', handleSelectorClick)
    );
}
init();
.body-ct .selector{display:inline-block;width:200px;text-align:center;border:1px solid navy;border-radius:4px;}
.body-ct .selector:hover{cursor:pointer;}
.body-ct .selector h4{padding:5px 0;}
.body-ct .selector {position:relative;}
.body-ct .selector .dropdown{display:none;position:absolute;top:55px;z-index:2;width:200px;border:3px solid red;background-color:#FFF;}
/*.body-ct .selector .dropdown.active{display:block;}*/
.body-ct .selector.active .dropdown {display:block;}
.body-ct .selector .dropdown ul{list-style-type:none;text-align:left;background-color:#FFF;}
.body-ct .selector .dropdown ul li{background-color:#FFF;}
.body-ct .selector .dropdown ul li:hover{font-weight:700;}
<section class="body-ct">
  <div class="container">
    <div class="row">
      <div class="col-12 sel-ct">
        <div class="story-type-sel selector">
          <h4>Story Type</h4>
          <div class="dropdown story-selector">
            <ul>
              <li data-type="article">Article</li>
              <li data-type="pr">Press Release</li>
              <li data-type="analyst">Analyst Report</li>
            </ul>
          </div>
        </div>
        <div class="year-sel selector">
          <h4>Year</h4>
          <div class="dropdown year-selector">
            <ul>
              <li data-year="2021">2021</li>
              <li data-year="2020">2020</li>
              <li data-year="2019">2019</li>
              <li data-year="2018">2018</li>
            </ul>
          </div>
        </div>
      </div>  
    </div>
  </div>
</section>

于 2021-06-08T18:50:51.973 回答
1

问题是返回代码中所有元素document.querySelectorAll()的数组,并返回他找到的第一个元素,但不一定是触发事件的元素内的元素。dropdowndocument.querySelector()

如果要将类添加到单击active元素中包含的下拉元素中,则可以从事件当前目标调用,而不是从:selectorquerySelector()document

document.querySelectorAll('.selector').forEach((item) => {
  item.addEventListener("click", (event) => {
    event.currentTarget.querySelector('.dropdown').classList.add("active");
  });
});
于 2021-06-08T18:48:52.893 回答
1

querySelectorAll 返回一个节点列表。使用 forEach。

document.querySelectorAll('.selector').forEach((item) => {
  item.addEventListener("click", (event) => {
    event.target.querySelectorAll(".dropdown").forEach((dopdownItem) => {
      dopdownItem.classList.add("active");
    });
  });
});
.body-ct .selector {
  display: inline-block;
  width: 200px;
  text-align: center;
  border: 1px solid navy;
  border-radius: 4px;
}

.body-ct .selector:hover {
  cursor: pointer;
}

.body-ct .selector h4 {
  padding: 5px 0;
}

.body-ct .selector {
  position: relative;
}

.body-ct .selector .dropdown {
  display: none;
  position: absolute;
  top: 55px;
  z-index: 2;
  width: 200px;
  border: 3px solid red;
  background-color: #FFF;
}

.body-ct .selector .dropdown.active {
  display: block;
}

.body-ct .selector .dropdown ul {
  list-style-type: none;
  text-align: left;
  background-color: #FFF;
}

.body-ct .selector .dropdown ul li {
  background-color: #FFF;
}

.body-ct .selector .dropdown ul li:hover {
  font-weight: 700;
}
<section class="body-ct">
  <div class="container">
    <div class="row">
      <div class="col-12 sel-ct">
        <div class="story-type-sel selector">
          <h4>Story Type</h4>
          <div class="dropdown story-selector">
            <ul>
              <li data-type="article">Article</li>
              <li data-type="pr">Press Release</li>
              <li data-type="analyst">Analyst Report</li>
            </ul>
          </div>
        </div>
        <div class="year-sel selector">
          <h4>Year</h4>
          <div class="dropdown year-selector">
            <ul>
              <li data-year="2021">2021</li>
              <li data-year="2020">2020</li>
              <li data-year="2019">2019</li>
              <li data-year="2018">2018</li>
            </ul>
          </div>
        </div>
      </div>
    </div>
  </div>
</section>

于 2021-06-08T18:50:09.160 回答