如何在尚未在 DOM [no-jQuery] 中的元素上添加事件侦听器?

RavenJeGames

我想将事件侦听器(调用函数)附加到 DOM 中尚不存在的按钮。我不想在 HTML 中使用 inline-call 我该怎么做?

到目前为止,我可以通过创建一个global event listener检查点击的元素是否具有特定 Id来实现我想要的但是我发现这个解决方案很脏而且不是最佳的。

const messageForm = document.querySelector("#message-form")
const messageTextarea = document.querySelector("#message-textarea");
const messageList = document.querySelector("#message-list");
const messageEmpty = document.querySelector("#message-empty");
let messageNumber = 0;

const messageFormatted = messageText => {
  return `
  <li class="message-item">
    <img class="message-avatar" src="./icons/boy.png" alt="Username">
      <article class="message-content">
        <p class="author">Ernesto Campese</p>
        <p class="message">${messageText}</p>
        <p class="datetime">A moment ago</p>
      </article>
      <div class="message-actions">
        <img id="message-edit" class="action-button" src="./icons/edit.png" alt="" width="22" height="22">
        <img id="message-delete" class="action-button" src="./icons/delete.png" alt="" width="22" height="22">
      </div>
  </li>
  `;
}

document.addEventListener("click", (e) => {
  if (e.target.id === "message-delete") {
    e.target.parentNode.parentNode.remove();
    messageNumber--;
    messageEmptyCheck();
  }
})

messageForm.addEventListener("submit", (e) => {
  e.preventDefault();
  if (messageTextarea.value !== "") {
    messageList.insertAdjacentHTML("beforeend", messageFormatted(messageTextarea.value));
    messageTextarea.value = null;
    messageTextarea.focus();
    messageNumber++;
    messageEmptyCheck();
  }
});

正如您在代码中看到的,在<li>我创建的内部有两个 IMG,一个用于删除,另一个用于编辑。我想为删除IMG添加一个事件侦听器,因此当用户单击它时,li会被消除。

问题是如果该元素尚不存在,我将无法创建任何函数。我想做类似的事情:

const messageDeleteButton = document.querySelector("#message-delete");

messageDeleteButton.addEventListener("click", (e) => {
    e.parentNode.parentNode.remove();
  }
})

希望我说的够清楚了,谢谢大家!

埃米尔·祖比尔

您可以将 HTML 字符串解析为documentJS 中的 a,然后将事件侦听器添加到该元素。

所以你有你的模板文字字符串。

const messageFormatted = messageText => {
  return `
  <li class="message-item">
    <img class="message-avatar" src="./icons/boy.png" alt="Username">
      <article class="message-content">
        <p class="author">Ernesto Campese</p>
        <p class="message">${messageText}</p>
        <p class="datetime">A moment ago</p>
      </article>
      <div class="message-actions">
        <img id="message-edit" class="action-button" src="./icons/edit.png" alt="" width="22" height="22">
        <img id="message-delete" class="action-button" src="./icons/delete.png" alt="" width="22" height="22">
      </div>
  </li>
  `;
}

您可以string通过编写如下所示的函数将您的内容转换为 HTML。它使用DOMParser API来创建一个新的document,它将包含您在string.

const parseStringToHTML = (str) => {
  const parser = new DOMParser();
  return parser.parseFromString(str, 'text/html');
};

并且这个文档就像你在你的页面中拥有的一样,它只是一个新的,暂时只存在于你的 JS 内存中。提供您的stringas 参数parseStringToHTML以创建 HTML。

const message = messageFormatted('This is the message'); // Example message
const messageHTML = parseStringToHTML(message); // Returns a document object with all the features a document object has.

所以,现在你string是一个document你可以使用的方法就可以了像getElementByIdquerySelector等,但首先你必须选择你所需要的元素。

const messageDeleteButton = messageHTML.querySelector("#message-delete");

看到我使用了messageHTML而不是document. 在这种情况下messageHTML a document,因此我们可以在其中查询。现在你已经在里面找到了你的元素,document你可以向它添加一个事件监听器。

messageDeleteButton.addEventListener("click", (e) => {
    e.parentNode.parentNode.remove();
});

好的,现在已经添加了事件侦听器。您现在要做的就是将您需要的 HTML 从 附加messageHTMLdocument您的页面中。HTML 可以在messageHTML.body属性中找到

现在代替insertAdjacentHTML用于insertAdjacentElement在您选择的位置插入元素。要附加的元素是<li class="message-item">这将是firstElementChildbody中的messageHTML.body财产。

因此,在submit表单的事件侦听器中,将以下行更改为:

messageList.insertAdjacentHTML("beforeend", messageFormatted(messageTextarea.value));

对于我在上面解释的所有内容。

// Create string
const message = messageFormatted(messageTextarea.value);

// String to document
const messageHTML = parseStringToHTML(message);

// Select delete element.
const messageDeleteButton = messageHTML.querySelector("#message-delete");

// Add event listener to delete element.
messageDeleteButton.addEventListener("click", (e) => {   
    e.parentNode.parentNode.remove();
});

// Append the <li> element to the messageList.
messageList.insertAdjacentElement("beforeend", messageHTML.body.firstElementChild); 

不要忘记parseStringToHTML在代码中包含该函数。我知道这是很多工作,所以如果你有任何问题,请提出。

我希望这会帮助你。

请注意,我看到事件委托(全局事件侦听器)不是您想要做的事情,尽管正如其他人所说,它比其他方法(甚至是我自己的答案)更高效且更易于实现。它还可以解决侦听您已添加或什至从列表中删除的元素的问题。您甚至可以在TJ Crowder 建议<ul id="message-list">元素上设置它

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

在调试时或从JavaScript代码中如何在DOM节点上查找事件侦听器?

使用jQuery将事件侦听器添加到动态添加的元素中

作用域变量在事件侦听器更改后未在DOM中更新

如何从父级中删除jQuery事件侦听器而不删除类似的侦听器?

如何在jquery的sweetalert对话框中为html按钮添加事件侦听器

如何添加触发将某种类型的元素添加到DOM的事件侦听器?

将事件侦听器添加到Angular 4中的DOM元素

从已删除的DOM元素中分离jQuery侦听器

如何将事件侦听器添加到ag网格的单元格内的元素(使用js或jquery,不是Angular,不是reactjs,不是vue)

如何在jQuery中的复选框数组上设置侦听器?

如何在Jquery中多次调用函数以添加事件侦听器,而不仅仅是侦听最后一个?

如何将事件侦听器添加到数组中的每个元素?

如何使用jquery .each()添加单个事件侦听器?

jQuery-如何为动态添加的可放置表格行实现事件侦听器?

iOS UIWebView:如何将侦听器添加到DOM事件?

如何从尚未添加到DOM的JQuery对象中删除特定元素?

如果我使用jQuery更改div的HTML,是否从内存中删除了所有DOM元素和侦听器?

如何为没有JQuery动态创建的元素创建事件侦听器

jQuery在不同的DOM层次结构中委派的事件侦听器-是否会触发适用的事件侦听器?

在替换的HTML DOM上添加事件侦听器

如何在Polymer中的自定义元素属性中添加事件侦听器?

如何在DOM元素上查找事件侦听器列表?

jQuery面向对象的创建dom元素并添加事件侦听器

如何使用 redux-observable 在 dom 元素上添加事件侦听器

如何让 DOM/事件侦听器知道新添加的节点?

className加载dom后如何设置事件侦听器

向推入数组的 DOM 元素添加事件侦听器

如何在 JQuery 中为动态创建的具有相同类名的链接添加事件侦听器?

如何使用 jQuery 在类构造函数上添加事件侦听器?