对于每个都不起作用的单击创建的元素

时间:2019-07-16 16:48:27

标签: javascript foreach

我想要的是:每当我单击任何“ hello”世界时,它都应该提醒我“ Hello”,即使在这些“ Hello's”中,它们都是按按钮创建的

这是我尝试过For(of)ForEach()的代码,但对我没有用

这是我的尝试

let btn = document.getElementById("kick");
btn.onclick = function() {
  let NewP = document.createElement("p");
  let createText = document.createTextNode("Hello");
  NewP.appendChild(createText);
  NewP.classList.add("hello");
  document.body.appendChild(NewP);
}
let allClasshello = document.getElementsByClassName("hello");
let allClasshelloAr = Array.from(allClasshello);
allClasshelloAr.forEach(function popup(elemetnWithHello) {
  elemetnWithHello.onclick = function() {
    window.alert("Hello")
  }
})
<p class="hello">Hello</p>
<button id="kick">Create ME</button>

JavaScript的新功能

6 个答案:

答案 0 :(得分:0)

forEach仅在用户添加任何元素之前在此代码的开头被调用,因此onclick事件仅添加到第一个。您需要向每个新添加的元素添加onclick函数:

btn.onclick = function(){
   let NewP = document.createElement("p");

   ...

   NewP.onclick = function(){
       window.alert("Hello")
   }
}

答案 1 :(得分:0)

您需要设置事件处理程序,以便知道何时单击元素。我的示例使用了一种称为event delegation的技术,这基本上意味着我们向父DOM元素添加了一个事件处理程序-然后,当事件冒泡时,我们检查event.target以查看被单击的确切元素。

类似如下的内容-检查代码中的注释:

// Vars to keep a reference to your DOM elements
const buttonEl = document.querySelector('#buttonEl');
const containerEl = document.querySelector('#containerEl');

// Event handling functions 
const pHandler = e => {
  if (e.target.tagName === 'P') { //This line also part of the event delegation
    console.log(e.target.textContent);
  }
};

const buttonHandler = (e, containerEl) => {
  const pEl = document.createElement("p");
  pEl.appendChild(document.createTextNode("Hello"));
  containerEl.appendChild(pEl);
};

//Add the click handlder to the button so it will create more elements when clicked
buttonEl.addEventListener('click', e => buttonHandler(e, containerEl))

//Add a click handler to the parent container - this is called event delegation
containerEl.addEventListener('click', pHandler)
<input id="buttonEl" type="button" value="Create HELLO" />

<div id="containerEl">
  <p class="hello">Hello</p>
</div>

答案 2 :(得分:0)

您可以在创建新元素时添加onclick事件。

let btn = document.getElementById("kick");
btn.onclick = function() {
  let NewP = document.createElement("p");
  let createText = document.createTextNode("Hello");
  NewP.appendChild(createText);
  NewP.onclick = popup;
  NewP.classList.add("hello");
  document.body.appendChild(NewP);
}

function popup() {
  window.alert("Hello")
}
<p class="hello" onclick="popup()">Hello</p>
<button id="kick">Create ME</button>

答案 3 :(得分:0)

您必须区分同步代码和异步代码。

let btn = document.getElementById("kick");
btn.onclick = async;
let allClasshello = document.getElementsByClassName("hello");
let allClasshelloAr = Array.from(allClasshello);
allClasshelloAr.forEach(function popup(elemetnWithHello) {
  elemetnWithHello.onclick = async;
})

因此,在调用forEach的那一刻,没有调用btn.onclick处理程序,仅到达DOM上存在的<p class="hello">

接受代码,创建元素的时刻就是.hello处理程序的时候了。

let btn = document.getElementById("kick");
btn.onclick = function() {
  let NewP = document.createElement("p");
  let createText = document.createTextNode("Hello");
  NewP.appendChild(createText);
  NewP.classList.add("hello"); // you dont need this if isn't used by CSS
  NewP.onclick = handleHelloClick;
  document.body.appendChild(NewP);
}
let allClasshello = document.getElementsByClassName("hello");
let allClasshelloAr = Array.from(allClasshello);
allClasshelloAr.forEach(function popup(elemetnWithHello) {
  elemetnWithHello.onclick = handleHelloClick;
})
function handleHelloClick() {
  window.alert("Hello")
}

如果您有用于这些<p>的容器,则可以利用addEventListener API,订阅该容器而不是每个元素...

let container = document.createElement("div");
container.addEventListener("click", containerClickHandler);
document.body.appendChild(container);

function containerClickHandler() {
   window.alert("Hello");
}

let btn = document.getElementById("kick");
btn.onclick = function() {
  let NewP = document.createElement("p");
  let createText = document.createTextNode("Hello");
  NewP.appendChild(createText);
  container.appendChild(NewP);
}

答案 4 :(得分:0)

运行forEach时,没有段落元素(NewP)。为了解决这个问题,我建议有两种选择:

  • 将onclick事件侦听器添加到创建它的NewP元素中。
  • 还有另一个操作可以按需调用下面的代码(包装在函数中)以分配onclick事件监听器

以下是示例工作解决方案:

答案 5 :(得分:0)

对于动态创建的元素,在创建它们时(在将它们附加到click之前),必须附加通风孔侦听器(在这种情况下,这是一个document事件)。 / p>

请参阅下一个示例:

const btn = document.getElementById('kick'),
  alreadyInDocHello = document.querySelectorAll('.hello'); /** selecting the already in the document element to handle click event (those created dynamically will not be included here) **/
  sayHello = e => {
    e && e.preventDefault();
    alert('Hello !');
  }; /** sayHello is the function that will be called when having a click event (basically it'll show an alert saying "hello !" **/

/** add click listener for create button **/
btn.addEventListener('click', e => {
  let newEl = document.createElement('p'),
    createText = document.createTextNode('Hello');
  e.preventDefault();
  newEl.appendChild(createText);
  newEl.classList.add('hello');
  /** add the listener here **/
  newEl.addEventListener('click', sayHello); /** don't forget that sayHello is declared above **/
  document.body.appendChild(newEl);
});

/** click event listener for those elements that are already present in the document **/
alreadyInDocHello.forEach(el => el.addEventListener('click', sayHello));
.hello {
  background: #242424;
  color: #fff;
  padding: 15px;
  text-align: center;
  transition: all .4s 0s ease;
}

.hello:hover {
  background: #ccc;
  color: #000;
}
<p class="hello">Hello</p>
<button id="kick">Create ME</button>

  

详细了解addEventListener函数。