删除第一个元素后事件不会克隆

时间:2019-08-24 22:46:51

标签: javascript jquery

我应该用Jquery克隆一些元素,并且效果很好,但是当我删除要用它克隆其他元素的第一个元素之后,新克隆的元素就没有应该具有的事件了!

我尝试了.clone(true, true)方法,它克隆了事件,但是在删除第一个元素之后没有。

var card = $(".newCard"); //class name of first element
$("#addBtn0").click(function() {
   $(".row").append(card.clone(true, true)); //it works well but...
});

$("[class^=btnDelete]").click(function() {
    $(this).closest(".newCard").remove(); //it works too but not after deleting first element and creating again
});

我不知道为什么会这样,实际上,即使删除第一个元素并重新创建,每个元素都应该具有事件。

3 个答案:

答案 0 :(得分:4)

问题在于click事件被绑定到该第一个元素,结果绑定与该元素一起被删除。处理动态元素时,应在静态元素上使用.on方法来使用event delegation。例如文档本身。

编辑:在这样的小型文档上,您不会注意到任何性能问题,但是将文档用作事件委托者可能会在较大的文档上导致性能问题。您可以了解有关事件委托性能here的更多信息。

var card = $(".newCard");
$("#addBtn0").click(function() {
  $(".row").append(card.clone(true, true));
});
$(document).on('click', '.btnDelete', function() {
  $(this).closest(".newCard").remove();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="addBtn0">Add</button>
<div class="row">
  <div class="newCard">Card <button class="btnDelete">Delete</button></div>
</div>

答案 1 :(得分:1)

这是由于

$("[class^=btnDelete]").click(function() {

上一行将定位现有(!!!)元素及其内部按钮。
由于您要克隆该现有元素,因此您还需要克隆绑定到其按钮创建上的事件。
一旦删除了card(存储在变量中),您还将销毁与其绑定的事件。

要解决此问题,请使用.on()动态事件委托

$(".row").on('click', '[class^=btnDelete]', function() {

var card = $(".newCard"); //class name of first element

$("#addBtn0").click(function() {
  $(".row").append(card.clone(true, true));
});
$(".row").on('click', '[class^=btnDelete]', function() {
  $(this).closest(".newCard").remove();
});
<div class="row">
  <div class="newCard">CARD <button class="btnDelete">DELETE</button></div>
</div>
<button id="addBtn0">ADD</button>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

https://api.jquery.com/on/#direct-and-delegated-events

其他问题和解决方案

代码中的其他问题主要是命名问题。 [class^=btnDelete]只是在等待您一天,将样式类添加到该功能较差的按钮上,然后您的JavaScript惨遭失败。另外,为什么btnAdd00?为什么要.clone(true, true)

这是一个更好的重写:

const $Cards = $('.Cards');
const $Cards_add = $('.Cards-btn--add');
const $Cards_item = (html) => {
 const $self = $('<div/>', {
    appendTo: $Cards,
    class: `Cards-item`,
    html: html || `New Card`,
  });

  $('<button/>', {
    appendTo: $self,
    class: `Cards-btn Cards-btn--delete`,
    text: `Delete`,
    on: {
      click() {
        $self.remove();
      }
    },
  });
}

let card_id = 0;
$Cards_add.on('click', () => $Cards_item(`This is Card ${++card_id}`));

// Create some dummy cards
$Cards_item(`This is Card ${++card_id}`);
$Cards_item(`This is Card ${++card_id}`);
$Cards_item(`This is Card ${++card_id}`);
/**
 * Cards component styles
 */

.Cards {} /* scss extend .row or rather define styles directly */

.Cards-item { padding: 5px; margin: 5px 0; background: #eee; }
.Cards-btn { }
.Cards-btn--add { color: blue; }
.Cards-btn--delete { color: red; }
<div class="Cards"></div>
<button class="Cards-btn Cards-btn--add">ADD</button>

<script src="//code.jquery.com/jquery-3.4.1.js"></script>

答案 2 :(得分:-1)

$(".row").append(card.clone(true, true));

您仍在使用$('.newCard')的原始结果,该结果不包括您添加的任何新卡。

$(".row").append($(this).parent().clone(true, true)); 

这有效