querySelectorAll 使用 insertAdjacentHTML 加载内容后返回空 NodeList

问题描述 投票:0回答:2

情况:

  • 我正在将内容从数据库加载到我的 HTML 网站,并使用
    insertAdjacentHTML
    将其插入。 内容也显示正确,所有数据都在这里
  • 我想在单击之前插入的元素之一时展开卡片。
  • 我的事件侦听器可以很好地处理我的测试 HTML 内容,但不能处理插入的内容。整个事情不起作用,因为
    .querySelectorAll
    返回一个空的 NodeList。

我尝试放置脚本,将内容加载到头部和将事件侦听器保留到末尾的脚本中,但没有任何变化。实际上,用开发者工具观看时,内容就在 HTML 文件中。

这是模板:

let markup = `
    <figure class="control__msg" id="${snapshot.key}">
      <div class="control__msg--info">
        <h4>${item.name}</h4>
        <h5>${item.time}</h5>
      </div>
      <div class="control__msg--content" id="content_${snapshot.key}">
        <h4>Email: ${item.email}</h4>
        <h4>Tel.: ${item.phone}</h4>
        <h4>Betreff: ${item.subject}</h4>
        <p>
          ${item.message}
        </p>
      </div>
    </figure>`;

    document.getElementById('messages').insertAdjacentHTML('beforeend', markup);

这是事件监听器:

document.addEventListener('DOMContentLoaded', e => {
  let targets = document.querySelectorAll('.control__msg');

  targets.forEach(curr => {
    curr.addEventListener('click', e => {
      let content = document.getElementById(`content_${curr.id}`);

      if (content.style.display === 'block') {
        content.style.display = 'none';
      } else {
        content.style.display = 'block';
        content.style.animation = 'dropIn .8s 0s forwards ease-out';
      }
    });
  });
});
javascript html selectors-api insertadjacenthtml
2个回答
0
投票

我也遇到过类似的情况,以下js代码:

window.selectMode = function() {
    // ...
    const atext = document.querySelectorAll('a.atext');
    console.log('selectMode - atext:', atext);
    // ...
}

//  Option 1:
    document.addEventListener('DOMContentLoaded', selectMode);

//  Option 2:
    document.addEventListener('DOMContentLoaded', function() {selectMode();});

使用选项 1,执行 selectMode 函数,但 atext 为空。当函数执行时(例如 onclick 事件),稍后会填充文本。

使用选项 2,执行 selectMode 函数并返回填充的节点列表 atext。

所以这似乎取决于 addEventListener 的使用方式。


0
投票

问题中没有描述任何内容或 HTML,所以我只是发明了一些。

在这里,我使用委托引用来处理

#messages
容器内的点击,并通过 CSS 中的
hidden
类切换显示/隐藏。有很多方法可以完成此操作,而不是切换一个类,例如具有值的数据属性,如下所示:https://stackoverflow.com/a/75405196/125981

function insertNewBlock(item, index) {
  //  console.log(item, index);
  const snapshot = snapshots[index];
  let markup = `
    <figure class="control__msg" id="snapshot-${snapshot.key}">
      <div class="control__msg--info">
        <h4>${item.name}</h4>
        <h5>${item.time.toLocaleTimeString()}</h5>
      </div>
      <div class="control__msg--content" id="content_${snapshot.key}">
        <h4>Email: ${item.email}</h4>
        <h4>Tel.: ${item.phone}</h4>
        <h4>Betreff: ${item.subject}</h4>
        <p>
          ${item.message}
        </p>
      </div>
    </figure>`;

  document.getElementById('messages')
    .insertAdjacentHTML('beforeend', markup);
}

const items = [{
  name: "Barney",
  email: "[email protected]",
  time: new Date(),
  phone: "123-456-7890",
  subject: "books for everyone",
  message: "We all need books"
}, {
  name: "Wilber",
  email: "[email protected]",
  time: new Date(),
  phone: "123-111-1111",
  subject: "books for everyone",
  message: "I need a book also!"
}, {
  name: "Wilma",
  email: "[email protected]",
  time: new Date(),
  phone: "123-111-1111",
  subject: "books for everyone",
  message: "I need a rick book today!"
}];

const snapshots = [{
  key: 0,
  value: "base"
}, {
  key: 1,
  value: "glove"
}, {
  key: 2,
  value: "bat"
}, {
  key: 3,
  value: "ball"
}];

document.addEventListener('DOMContentLoaded', (e) => {
  items.forEach(insertNewBlock);
  const messageContainer = document.querySelector('#messages');
  //  document.querySelectorAll('.control__msg');
  messageContainer.addEventListener('click', (event) => {
    const messages = Array.prototype.slice.call(event.target.children);
    //   console.log(event.target); //where I clicked
    //   console.log(event.currentTarget); //the messages container
    const targ = event.target.closest('.control__msg');
    const msgIndex = messages.indexOf(targ)
    const content = targ.querySelector('.control__msg--content');
    //   console.log(content);
    const classes = content.classList;
    classes.toggle("hidden");
  });
});
.content {}

.control__msg {
  display: grid;
  place-items: center;
  border: solid 1px #00FF00;
  background-color: #00ff0020;
}

.control__msg--content {
  border: solid #FF0000;
  padding: 1em;
  animation: .8s 0s forwards ease-out;
}

.control__msg--content.hidden {
  display: none;
}
<div id="messages"></div>

© www.soinside.com 2019 - 2024. All rights reserved.