如何在加载元素后触发事件?

时间:2018-05-23 07:18:00

标签: 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">&#10006;&nbsp;</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';
	}
}
&#13;
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;
}
&#13;
<!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">&nbsp;
	<input type="button" value="Get Tags" id="getTags">
	<br>
	<br>
	<ul id="ul"></ul>
</body>
</html>
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:2)

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">&#10006;&nbsp;</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">&nbsp;
  <input type="button" value="Get Tags" id="getTags">
  <br>
  <br>
  <ul id="ul"></ul>
</body>

</html>