将事件侦听器应用于 <divs> 时遇到问题
Having trouble applying event listeners to <divs>
大家好,我正在创建一个电子邮件应用程序,但在为每个用户将电子邮件打印到收件箱屏幕时遇到了问题。收件箱中的每封电子邮件都是 .我想为每个事件附加一个 onclick 事件侦听器,以便可以点击它,如果您点击它,您将获得一个包含电子邮件实际完整正文的页面。
我的函数 open_email() 接受一个参数,即电子邮件 ID。这就是我将用来调出电子邮件的内容。但我需要传入正确的 ID。
它现在的工作方式是 ID 始终为“1”,这是我创建的第一封电子邮件的 ID。
我不明白为什么要将每个 ID 更改为“1”。我缺少的循环中的代码一定有问题。
有人能找到吗?谢谢!
if (mailbox == "inbox") {
fetch('/emails/inbox')
.then(response => response.json())
.then(emails => {
const element = document.getElementById("emails-view");
for (index = 0; index < emails.length; index++) {
var x = emails[index].id
if (emails[index].read == false) {
element.innerHTML += '<div class="emails unread">' + "From:" + JSON.stringify(emails[index].sender) +
"<p class='subject'>" + "Subject: " + JSON.stringify(emails[index].subject) + "</p>" + JSON.stringify(emails[index].timestamp) + '</div>';
element.onclick = () => open_email(x)
}else{
element.innerHTML += '<div class="emails">' + "From:" + JSON.stringify(emails[index].sender) +
"<p>" + "Subject: " + JSON.stringify(emails[index].subject) + "</p>" + JSON.stringify(emails[index].timestamp) + '</div>';
element.onclick = () => open_email(x)
}
}
});
您正在向 整个容器 添加一个事件侦听器,并在循环的每次迭代中覆盖它。相反,向附加元素添加一个侦听器。
一个问题是使用 innerHTML +=
会破坏容器内的现有侦听器,因此请改用 appendChild
:
const container = document.getElementById("emails-view");
for (const email of emails) {
const { read, id, timestamp, sender, subject } = email;
const emailDiv = container.appendChild(document.createElement('div'));
emailDiv.className = read ? 'emails' : 'emails unread';
emailDiv.innerHTML = `
From: ${JSON.stringify(sender)}
<p class='subject'>Subject: ${JSON.stringify(subject)}</p> ${timestamp}
`;
emailDiv.onclick = () => open_email(id);
}
这是一般的想法 - 但还有另一个问题。连接来自用户输入的 HTML 个字符串会导致任意代码执行。为防止不安全代码成为 运行,请确保放入 HTML 的值不包含 HTML 标记定界符(<
和 >
) .
const clean = str => str
.replaceAll('<', '<')
.replaceAll('>', '>');
并使用,例如:
From: ${JSON.stringify(clean(sender))}
或者,更好的是,在将文本放入数据库之前对其进行清理。
(你真的到处都需要 JSON.stringify
吗?这看起来很奇怪,如果可以的话请删除它)
大家好,我正在创建一个电子邮件应用程序,但在为每个用户将电子邮件打印到收件箱屏幕时遇到了问题。收件箱中的每封电子邮件都是 .我想为每个事件附加一个 onclick 事件侦听器,以便可以点击它,如果您点击它,您将获得一个包含电子邮件实际完整正文的页面。
我的函数 open_email() 接受一个参数,即电子邮件 ID。这就是我将用来调出电子邮件的内容。但我需要传入正确的 ID。
它现在的工作方式是 ID 始终为“1”,这是我创建的第一封电子邮件的 ID。
我不明白为什么要将每个 ID 更改为“1”。我缺少的循环中的代码一定有问题。
有人能找到吗?谢谢!
if (mailbox == "inbox") {
fetch('/emails/inbox')
.then(response => response.json())
.then(emails => {
const element = document.getElementById("emails-view");
for (index = 0; index < emails.length; index++) {
var x = emails[index].id
if (emails[index].read == false) {
element.innerHTML += '<div class="emails unread">' + "From:" + JSON.stringify(emails[index].sender) +
"<p class='subject'>" + "Subject: " + JSON.stringify(emails[index].subject) + "</p>" + JSON.stringify(emails[index].timestamp) + '</div>';
element.onclick = () => open_email(x)
}else{
element.innerHTML += '<div class="emails">' + "From:" + JSON.stringify(emails[index].sender) +
"<p>" + "Subject: " + JSON.stringify(emails[index].subject) + "</p>" + JSON.stringify(emails[index].timestamp) + '</div>';
element.onclick = () => open_email(x)
}
}
});
您正在向 整个容器 添加一个事件侦听器,并在循环的每次迭代中覆盖它。相反,向附加元素添加一个侦听器。
一个问题是使用 innerHTML +=
会破坏容器内的现有侦听器,因此请改用 appendChild
:
const container = document.getElementById("emails-view");
for (const email of emails) {
const { read, id, timestamp, sender, subject } = email;
const emailDiv = container.appendChild(document.createElement('div'));
emailDiv.className = read ? 'emails' : 'emails unread';
emailDiv.innerHTML = `
From: ${JSON.stringify(sender)}
<p class='subject'>Subject: ${JSON.stringify(subject)}</p> ${timestamp}
`;
emailDiv.onclick = () => open_email(id);
}
这是一般的想法 - 但还有另一个问题。连接来自用户输入的 HTML 个字符串会导致任意代码执行。为防止不安全代码成为 运行,请确保放入 HTML 的值不包含 HTML 标记定界符(<
和 >
) .
const clean = str => str
.replaceAll('<', '<')
.replaceAll('>', '>');
并使用,例如:
From: ${JSON.stringify(clean(sender))}
或者,更好的是,在将文本放入数据库之前对其进行清理。
(你真的到处都需要 JSON.stringify
吗?这看起来很奇怪,如果可以的话请删除它)