首页 > 解决方案 > 我可以使用 queryselector 和 foreach 在 javascript 中获取直接元素吗?

问题描述

我正在尝试制作一个确认控件,如果我愿意,我可以在一个页面上多次使用它。因此我使用了 HTML、Bootstrap 和 JavaScript。出于调试原因,我想避免使用 jQuery(尽可能)(我知道对于 Bootstrap,我仍然可能需要使用其中的一些)。

我的解决方案包含element.parentNode为了在单击时保持控件分离。我遇到的问题是单击时似乎无法从控件中获取特定按钮。querySelectorAll()我的意图是通过使用and来保持我的代码干净forEach(),但我似乎不成功:

const targetModal = $("#bs-modal-xl");
const positiveNodes = document.querySelectorAll(".foo");
const negativeNodes = document.querySelectorAll(".bar");

positiveNodes.forEach(node => node.addEventListener("click", function() {
  const thisNode = this;
  thisNode.classList.add("btn-success");
  thisNode.parentNode.querySelectorAll(".bar").forEach(node => node.classList.remove("btn-warning"));

  //How do I get the direct button containing the text "confirm?" after clicking any yes button and enable it?
  console.log(thisNode.parentNode.parentNode)
  console.log(thisNode.parentNode.parentNode.querySelectorAll("> button")); // returns Uncaught DOMException: Failed to execute 'querySelectorAll' on 'Element': '> button' is not a valid selector.
  console.log(thisNode.parentNode.parentNode.querySelectorAll("button")); // <-- returns nodelist of 3 buttons: "yes", "no" and "confirm?".
  console.log(thisNode.parentNode.parentNode.parentNode.querySelectorAll(".confirmation-box > button")); // <-- returns nodelist of the available "confirm?" buttons, in this case 2 of them.

  //I would not want the seperate ".confirmation-box" elements to interact with each other, these are independant elements.
}));

negativeNodes.forEach(node => node.addEventListener("click", function() {
  this.classList.add("btn-warning");
  this.parentNode.querySelectorAll(".foo").forEach(node => node.classList.remove("btn-success"));
}));
#foo-container {
  padding: 5px;
}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
<div class="modal" id="bs-modal-xl" tabindex="-1" role="dialog" aria-labelledby="myLargeModalLabel">
  <div class="modal-dialog modal-lg" role="document">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
        <h4 class="modal-title">Modal title</h4>
      </div>
      <div class="modal-body">
        <p>One fine body&hellip;</p>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
        <button type="button" class="btn btn-primary">Save changes</button>
      </div>
    </div>
  </div>
</div>

<div id="foo-container">
  <div class="confirmation-box">
    <div class="btn-group btn-group-lg" role="group" aria-label="...">
      <button type="button" class="btn btn-success foo">Yes</button>
      <button type="button" class="btn btn-warning bar">No</button>
    </div>
    <button type="button" class="btn btn-lg btn-danger" disabled>Confirm?</button>
  </div>

  <br />

  <div class="confirmation-box">
    <div class="btn-group btn-group-lg" role="group" aria-label="...">
      <button type="button" class="btn btn-success foo">Yes</button>
      <button type="button" class="btn btn-warning bar">No</button>
    </div>
    <button type="button" class="btn btn-lg btn-danger" disabled>Confirm?</button>
  </div>
</div>

JSFiddle

通过使用我自己的包含 class 的自定义元素来分隔控件.confirmation-box

控件的愿望是当点击“是”时,“确认?” 应删除按钮的禁用状态,而单击“否”,应禁用“确认?” 按钮。

是否可以使用querySelectorAll()and获得所需的元素forEach()?我可以避免循环(和使用索引)并使用这些方法吗?我忽略了什么吗?

所需元素应如下所示:单击时 -> 此 -> 查找父.confirmation-box元素 -> 查找子“确认?” 按钮。

标签: javascripthtml

解决方案


我猜是这样的

const confirmButton = thisNode.parentNode.parentNode.querySelector(".confirmation-box > button");

推荐阅读