Клонированный элемент по клику не работает Javascript [с использованием Vanila Js no JQuery] - PullRequest
0 голосов
/ 15 сентября 2018

let btn = document.querySelector('button'),
    ul = document.getElementById('lista');


btn.onclick = () =>{
    ele =  ul.children[0].cloneNode(true, true);
    ele.innerHTML = 'item #' + (ul.children.length +1)
    ul.appendChild(ele);

}

 
Array.prototype.forEach.call(ul.children , child => {
    child.onclick = () => {
        document.getElementById('heading').textContent = child.textContent;
        Array.prototype.forEach.call(ul.children, wald  =>{
            wald.classList.remove('active')
        })
        child.classList.add('active');
        
    }
})
 
*{
  
    padding: 0;
    box-sizing: border-box;
    font-family: Arial, Helvetica, sans-serif;
}

.container{
    width: 60%;
    margin: 30px auto;
    border: 1px solid;
    padding: 30px 10px;


}


.container h1{
    text-align: center;
    background-color: tomato;
    color: #fff;

}

.container button{
    padding: 10px 20px;
    background-color: tomato;
    font-weight: bold;
    font-size: 18px;
    color: #FFF;
    border: none;
    cursor: pointer;


}
.container button:active{
    transform: scale(.99)
}


.container ul li{
    list-style-position: inside;
    padding: 7px 15px
}

.active{
    background-color: tomato;
    color: #FFF;
}
<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8" />
    <title>Page Title</title>
    <link rel="stylesheet" href="css/app.css" />
</head>

<body>
    <div class="container">
        <h1 id="heading">item here ! </h1>
        <button>add item</button>
        <ul id="lista">
            <li>item #1</li>
            <li>item #2</li>
            <li>item #3</li>
        </ul>
    </div>
     
    <script src="js/app.js"></script>
</body>

</html>

проблема с клонированными элементами

первое событие этого кода для добавления новых клонированных элементов в <ul>, когда я нажимаюкнопкаВторое событие, когда я нажимаю на li, предполагается, что у него есть класс .active .., но во втором случае оно работает только с оригинальными элементами, а не с новыми.

, так каково решение для прикрепленияобработчик новых элементов?

Ответы [ 3 ]

0 голосов
/ 15 сентября 2018

Очевидно, что элементы "li", которые вы создаете нажатием на кнопку, не существуют, когда вы в первый раз просматриваете ul.children, поэтому слушатель событий не будет зарегистрирован ни в одном из вновь созданных элементов "li".

То, что вам нужно использовать, называется делегированием события. Слушайте клики по родителю или любому другому предку "#lista> li", чтобы щелчок обнаруживался независимо от того, какой элемент li нажат.

Что такое делегирование DOM Event?

let btn = document.querySelector('button'),
  ul = document.getElementById('lista');


btn.onclick = () => {
  ele = ul.children[0].cloneNode(true, true);
  ele.innerHTML = 'item #' + (ul.children.length + 1)
  ul.appendChild(ele);

}

document.addEventListener('click', function(event) {
  switch (true) {
    case event.target.matches('#lista>li'):
      [].forEach.call(document.querySelectorAll('#lista>li'), function(el) {
        el.classList.remove('active');
      })
      event.target.classList.add('active');

  }


})
* {
  padding: 0;
  box-sizing: border-box;
  font-family: Arial, Helvetica, sans-serif;
}

.container {
  width: 60%;
  margin: 30px auto;
  border: 1px solid;
  padding: 30px 10px;
}

.container h1 {
  text-align: center;
  background-color: tomato;
  color: #fff;
}

.container button {
  padding: 10px 20px;
  background-color: tomato;
  font-weight: bold;
  font-size: 18px;
  color: #FFF;
  border: none;
  cursor: pointer;
}

.container button:active {
  transform: scale(.99)
}

.container ul li {
  list-style-position: inside;
  padding: 7px 15px
}

.active {
  background-color: tomato;
  color: #FFF;
}
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8" />
  <title>Page Title</title>
  <link rel="stylesheet" href="css/app.css" />
</head>

<body>
  <div class="container">
    <h1 id="heading">item here ! </h1>
    <button>add item</button>
    <ul id="lista">
      <li>item #1</li>
      <li>item #2</li>
      <li>item #3</li>
    </ul>
  </div>

  <script src="js/app.js"></script>
</body>

</html>
0 голосов
/ 15 сентября 2018

После добавления нового элемента в DOM вам нужно установить onclick для этого элемента в.

let btn = document.querySelector('button'),
    ul = document.getElementById('lista');


btn.onclick = () =>{
    ele =  ul.children[0].cloneNode(true, true);
    ele.innerHTML = 'item #' + (ul.children.length +1)
    ul.appendChild(ele);
    onClick(ul.children, ele);
}

Array.prototype.forEach.call(ul.children , child => {
    onClick(ul.children, child);      
});

function onClick(children, child) {
    child.onclick = () => {
        document.getElementById('heading').textContent = child.textContent;
        Array.prototype.forEach.call(children, wald  =>{
            wald.classList.remove('active')
        })
        child.classList.add('active');
    }
}
 
*{
  
    padding: 0;
    box-sizing: border-box;
    font-family: Arial, Helvetica, sans-serif;
}

.container{
    width: 60%;
    margin: 30px auto;
    border: 1px solid;
    padding: 30px 10px;


}


.container h1{
    text-align: center;
    background-color: tomato;
    color: #fff;

}

.container button{
    padding: 10px 20px;
    background-color: tomato;
    font-weight: bold;
    font-size: 18px;
    color: #FFF;
    border: none;
    cursor: pointer;


}
.container button:active{
    transform: scale(.99)
}


.container ul li{
    list-style-position: inside;
    padding: 7px 15px
}

.active{
    background-color: tomato;
    color: #FFF;
}
<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8" />
    <title>Page Title</title>
    <link rel="stylesheet" href="css/app.css" />
</head>

<body>
    <div class="container">
        <h1 id="heading">item here ! </h1>
        <button>add item</button>
        <ul id="lista">
            <li>item #1</li>
            <li>item #2</li>
            <li>item #3</li>
        </ul>
    </div>
     
    <script src="js/app.js"></script>
</body>

</html>
0 голосов
/ 15 сентября 2018

Обработчик события вызывается только один раз в начале, поэтому он видит только существующие элементы. Мое исправление заключается в том, что обработчик событий вызывается каждый раз, когда добавляются новые элементы. Кроме того, чтобы оптимизировать его, вам не нужно каждый раз проходить цикл и добавлять прослушиватели событий для всех элементов. Только новые элементы получат добавленные слушатели событий при нажатии кнопки

let btn = document.querySelector('button'),
  ul = document.getElementById('lista');


btn.onclick = () => {
  ele = ul.children[0].cloneNode(true, true);
  ele.innerHTML = 'item #' + (ul.children.length + 1)
  ul.appendChild(ele);
  addHandlerToItem(ele);
}

var eventHandler = function() {
  Array.prototype.forEach.call(ul.children, child => {
    addHandlerToItem(child);
  });
}

var addHandlerToItem = function(child) {
  child.onclick = () => {
    document.getElementById('heading').textContent = child.textContent;
    Array.prototype.forEach.call(ul.children, wald => {
      wald.classList.remove('active')
    })
    child.classList.add('active');
  }
};


eventHandler();
* {
  padding: 0;
  box-sizing: border-box;
  font-family: Arial, Helvetica, sans-serif;
}

.container {
  width: 60%;
  margin: 30px auto;
  border: 1px solid;
  padding: 30px 10px;
}

.container h1 {
  text-align: center;
  background-color: tomato;
  color: #fff;
}

.container button {
  padding: 10px 20px;
  background-color: tomato;
  font-weight: bold;
  font-size: 18px;
  color: #FFF;
  border: none;
  cursor: pointer;
}

.container button:active {
  transform: scale(.99)
}

.container ul li {
  list-style-position: inside;
  padding: 7px 15px
}

.active {
  background-color: tomato;
  color: #FFF;
}
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8" />
  <title>Page Title</title>
  <link rel="stylesheet" href="css/app.css" />
</head>

<body>
  <div class="container">
    <h1 id="heading">item here ! </h1>
    <button>add item</button>
    <ul id="lista">
      <li>item #1</li>
      <li>item #2</li>
      <li>item #3</li>
    </ul>
  </div>

  <script src="js/app.js"></script>
</body>

</html>
...