我想将事件侦听器(调用函数)附加到 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 字符串解析为document
JS 中的 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 内存中。提供您的string
as 参数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
你可以使用的方法就可以了像getElementById
,querySelector
等,但首先你必须选择你所需要的元素。
const messageDeleteButton = messageHTML.querySelector("#message-delete");
看到我使用了messageHTML
而不是document
. 在这种情况下messageHTML
是a document
,因此我们可以在其中查询。现在你已经在里面找到了你的元素,document
你可以向它添加一个事件监听器。
messageDeleteButton.addEventListener("click", (e) => {
e.parentNode.parentNode.remove();
});
好的,现在已经添加了事件侦听器。您现在要做的就是将您需要的 HTML 从 附加messageHTML
到document
您的页面中。HTML 可以在messageHTML.body
属性中找到。
现在代替insertAdjacentHTML
用于insertAdjacentElement
在您选择的位置插入元素。要附加的元素是<li class="message-item">
这将是firstElementChild
在body
中的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] 删除。
我来说两句