I have cloned divs containing buttons that clone their parents. Upon trying to click the buttons, events are triggered 2n times such that clicking the second clone produces 4 other clones and so on:
$(".add").off("click").on("click", function(e) {
e.stopPropagation();
e.stopImmediatePropagation();
$(".cloneable").clone(true).appendTo(".container");
});
$(".rem").off("click").on("click", function() {
if (document.getElementsByClassName('container')[0].childElementCount > 1) {
$(".cloneable:last").remove();
}
});<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<div class="cloneable">
<div>
<a class="btn btn-primary add" role="button">Add cell</a>
<a class="btn btn-primary rem" role="button">Remove cell</a>
</div>
<iframe src="index.php"></iframe>
</div>
</div>Advertisement
Answer
A few things.
- It’s easier to use a deferred click handler.
- You were cloning all ‘cloneable’, not just the
first. jQuery will find allcloneableand clone them, not just your original. - Remove now removes the one you clicked on, not the last one.
- The
disabledclass will be added/removed to therembutton, depending on if there is only one left or not.
$(".container").on("click", ".add", function(e)
{
e.stopPropagation();
e.stopImmediatePropagation();
$(".container .rem").removeClass("disabled");
let $cloneable = $(".cloneable").first().clone(true);
$cloneable.appendTo(".container");
}).on("click", ".rem", function()
{
if($(this).hasClass("disabled") ) return;
$(this).closest(".cloneable").remove();
if($(".container .rem").length === 1)
$(".container .rem").addClass("disabled");
});.btn.btn-primary
{
background:#d5d5d5;padding:4px;cursor:pointer;
}
.btn.btn-primary.disabled
{
background:red;
}<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<div class="cloneable">
<div>
<a class="btn btn-primary add" role="button">Add cell</a>
<a class="btn btn-primary disabled rem" role="button">Remove cell</a>
</div>
<iframe src="trial37.php"></iframe>
</div>
</div>