javascript - 如何仅在加载元素后触发事件?
问题描述
我正在创建一个简单的标签系统。
我还添加了删除数组的功能。但是,我遇到了一个问题。每当我启动事件侦听器以删除项目时,我都会收到此错误:Uncaught TypeError: Cannot set property 'onclick' of undefined
.
我知道我收到此错误是因为该元素在 DOM 中不可见/未创建。由于标签仅在单击按钮后出现,如何仅在加载标签元素后启动事件?
这是代码:
const tagsInput = document.getElementById('tagsField');
const tagsBtn = document.getElementById('getTags');
const ul = document.getElementById('ul');
let tagsRemover = document.getElementsByClassName('removeTag');
let tagsElemnts = document.getElementsByClassName('tags');
let tagsContainer = [];
let getTags = () => {
if(tagsInput.value) {
tagsInput.classList.remove('hasError');
let tags = tagsInput.value.split(",");
let pure_tags = tags.map((x) => x.trim());
tagsContainer = [...pure_tags];
} else {
tagsInput.classList.add('hasError');
}
}
let showTags = () => {
if(tagsContainer.length > 0) {
tagsContainer.forEach((element) => {
let container = document.createElement('LI');
container.innerHTML = '<span class="removeTag">✖ </span>'+element;
container.className = 'tags';
ul.appendChild(container);
});
tagsContainer = [];
tagsInput.value = '';
}
}
tagsInput.addEventListener('input', getTags);
tagsBtn.addEventListener('click', showTags);
// I am doing i < 2 just for debug purpose
for(let i = 0; i < 2; i = i + 1) {
tagsRemover[i].onclick = () => {
tagsElemnts[i].style.display = 'none';
}
}
label {
font-size: 24px;
font-family: Roboto;
}
input[type=button] {
font-size: 18px;
border: none;
color: #fff;
padding: 0.6em 1.5em;
border-radius: 2em;
background: #ff4040;
cursor: pointer;
outline: none;
margin-left: 0.5em;
}
input[type=text] {
font-size: 1.4em;
padding: 0.4em 0.7em;
outline: none;
border: 2px solid #c2c2c2;
transition: all 150ms ease-in-out;
}
input[type=text]:focus {
border-color: #0095ff;
}
.tags {
list-style: none;
background: #03A9F4;
color: #fff;
font-family: Roboto, sans-serif;
padding: 0.5em 1em;
border-radius: 10em;
text-align: center;
display: inline;
font-size: 14px;
margin-left: 0.5em;
}
.removeTag {
color: #fff;
display: inline;
cursor: pointer;
}
.hasError {
border-color: #ff0023 !important;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Get Tags</title>
</head>
<body>
<label for="tags">Tags: </label>
<input type="text" id="tagsField">
<input type="button" value="Get Tags" id="getTags">
<br>
<br>
<ul id="ul"></ul>
</body>
</html>
解决方案
添加检查,tagsRemover[i]
错误将消失。
当前代码:
tagsRemover[i].onclick = () => {
tagsElemnts[i].style.display = 'none';
}
改成:
if (tagsRemover[i]) {
tagsRemover[i].onclick = () => {
tagsElemnts[i].style.display = 'none';
}
}
下面是工作代码片段:
const tagsInput = document.getElementById('tagsField');
const tagsBtn = document.getElementById('getTags');
const ul = document.getElementById('ul');
let tagsRemover = document.getElementsByClassName('removeTag');
let tagsElemnts = document.getElementsByClassName('tags');
let tagsContainer = [];
let getTags = () => {
if (tagsInput.value) {
tagsInput.classList.remove('hasError');
let tags = tagsInput.value.split(",");
let pure_tags = tags.map((x) => x.trim());
tagsContainer = [...pure_tags];
} else {
tagsInput.classList.add('hasError');
}
}
let showTags = () => {
if (tagsContainer.length > 0) {
tagsContainer.forEach((element) => {
let container = document.createElement('LI');
container.innerHTML = '<span class="removeTag">✖ </span>' + element;
container.className = 'tags';
ul.appendChild(container);
});
tagsContainer = [];
tagsInput.value = '';
}
}
tagsInput.addEventListener('input', getTags);
tagsBtn.addEventListener('click', showTags);
// I am doing i < 2 just for debug purpose
for (let i = 0; i < 2; i = i + 1) {
if (tagsRemover[i]) {
tagsRemover[i].onclick = () => {
tagsElemnts[i].style.display = 'none';
}
}
}
label {
font-size: 24px;
font-family: Roboto;
}
input[type=button] {
font-size: 18px;
border: none;
color: #fff;
padding: 0.6em 1.5em;
border-radius: 2em;
background: #ff4040;
cursor: pointer;
outline: none;
margin-left: 0.5em;
}
input[type=text] {
font-size: 1.4em;
padding: 0.4em 0.7em;
outline: none;
border: 2px solid #c2c2c2;
transition: all 150ms ease-in-out;
}
input[type=text]:focus {
border-color: #0095ff;
}
.tags {
list-style: none;
background: #03A9F4;
color: #fff;
font-family: Roboto, sans-serif;
padding: 0.5em 1em;
border-radius: 10em;
text-align: center;
display: inline;
font-size: 14px;
margin-left: 0.5em;
}
.removeTag {
color: #fff;
display: inline;
cursor: pointer;
}
.hasError {
border-color: #ff0023 !important;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Get Tags</title>
</head>
<body>
<label for="tags">Tags: </label>
<input type="text" id="tagsField">
<input type="button" value="Get Tags" id="getTags">
<br>
<br>
<ul id="ul"></ul>
</body>
</html>
推荐阅读
- angular - 防止以角度 6 下载 config.ts 文件
- netbeans - 在 Apache Netbeans 9.0 中更改主题
- google-cloud-platform - 使用 terraform 创建 google_sql_user 始终会重新创建资源
- swift - Swift4 - 意外发现 nil - 将图像设置为按钮
- php - PHP / 连接到 Sphinx 需要用户名 / 密码
- c# - 如何为 List 类型实体编写 Razor 代码?
- ios - iOS - 视图(ViewController),具有持久数据
- php - 无法从 PHP 创建视图,但可以从 phpMyAdmin
- c# - 如何使正则表达式正确验证信息?
- adonis.js - adonijs 身份验证失败,出现 401 错误,并使用正确的电子邮件和密码