javascript和dom操作

问题描述 投票:1回答:1

我的目标是在单击页面时删除和/或移动页面上按钮的父元素。 DOM似乎没有响应我的点击事件。我认为这与范围和全局变量有关,但我还是一个新手。这是我的代码的样子。

var startButton = document.querySelectorAll('button[data-action="start"]');
var deleteButton = document.querySelectorAll('button[data-action="delete"]');
var element = document.getElementsByTagName('section');
var firstChildElement = element.firstChild;

startButton.addEventListener("click", toStart);
deleteButton.addEventListener("click", deleter);

/*function declarations*/
function toStart() {
  element.insertBefore(this.parentNode, firstChildElement);
}

function deleter() {
  element.removeChild(this.parentNode);
}
<section>
  <article>
    <h2>Item One 😇</h2>
    <p>Lorem ipsum dolor sit amet</p>
    <button data-action="start">Move to start</button>
    <button data-action="delete">Delete</button>
  </article>
  <article>
    <h2>Item Two 👿</h2>
    <p>Lorem ipsum dolor sit amet</p>
    <button data-action="start">Move to start</button>
    <button data-action="delete">Delete</button>
  </article>
  <article>
    <h2>Item Three 👻</h2>
    <p>Lorem ipsum dolor sit amet</p>
    <button data-action="start">Move to start</button>
    <button data-action="delete">Delete</button>
  </article>
</section>
javascript html5 dom
1个回答
3
投票

那是因为你使用querySelectorAll(),它返回一个node list(一组节点),你不能在一个集合上添加一个事件监听器(调用.addEventListener())。您只能在单个节点上执行此操作。 .getElementsByTagName()也是如此。它还返回一个节点列表,你不能要求节点列表的.firstChild。您只能在节点上调用它。

您可以使用.querySelector()来获取与选择器匹配的第一个节点。

现在,如果要在所有按钮上设置事件,则需要循环遍历节点列表并为每个按钮调用.addEventListener()

但是,由于您希望所有按钮上都有相同的侦听器,因此使用event delegation会更有效,更少代码,因此我们允许事件“冒泡”到祖先元素,并在该更高级别元素处拦截事件一次。然后,我们可以检查哪个元素实际上触发了较低级别的事件并采取相应的行动。

// We're going to let all click events within the section be handled at the section level
// instead of setting up the same handlers on multiple elements.
let sec = document.querySelector("section");
sec.addEventListener("click", handleClick);

// When the event bubbles up to the section, this function will be called
// and it will automatically receive a reference to the event that triggered it
function handleClick(event){
  // The .target property of the event object refers to the lower-level ojbect
  // that actually initiated the event (either a start or delete button in our case).
  // We're going to need the nearest <article> ancestor of the button that was clicked
  // The closest() method finds the nearest ancestor element that matches the selector
  let art = event.target.closest("article");

  // We can check what the source of the event was and act accordingly
  // Since you've used data-* attributes, use the dataset API to test them
  if(event.target.dataset.action === "start"){
    toStart(art);
  } else if(event.target.dataset.action === "delete") {
    deleter(art);
  }
}

/*function declarations*/
function toStart(element){
  element.parentNode.insertBefore(element, element.parentNode.firstChild);
}

function deleter(element){
  element.parentNode.removeChild(element);
}
<section>
  <article>
    <h2>Item One 😇</h2>
    <p>Lorem ipsum dolor sit amet</p>
    <button data-action="start">Move to start</button>
    <button data-action="delete">Delete</button>
  </article>
  <article>
    <h2>Item Two 👿</h2>
    <p>Lorem ipsum dolor sit amet</p>
    <button data-action="start">Move to start</button>
    <button data-action="delete">Delete</button>
  </article>
  <article>
    <h2>Item Three 👻</h2>
    <p>Lorem ipsum dolor sit amet</p>
    <button data-action="start">Move to start</button>
    <button data-action="delete">Delete</button>
  </article>
</section>
© www.soinside.com 2019 - 2024. All rights reserved.