如何有效地管理多个自定义下拉 DOM 元素的行为和可见性状态?

如何解决如何有效地管理多个自定义下拉 DOM 元素的行为和可见性状态?

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");
});

解决方法

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

如果您想将 active 类添加到包含在被点击的 selector 元素中的下拉元素中,您可以从事件当前目标而不是从 {{ 1}}:

querySelector()
,

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>

,

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

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 这个 class 而是 toggle 它。

其中一个原因需要相应地更改相关切换行为的 css-selector。

上面的示例代码然后变成了下面的...

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>

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?