Reputation: 79
I have given an append function on a callback of addClass to an element. But that function executes twice. why?
//append new stage function---------//
var newNode;
function appendNewStage() {
var parent = $('.ci-journey-interactions-canvas__row');
var newStage = `<ul class="ci-journey-interactions-canvas__journey-list stage">
<li>
<span class="ci-journey-interactions-box__droppable-
element ci-droppable"></span>
</li>
</ul>`;
var position = $(parent).find("ul:last").position();
var width = $(parent).find("ul:last").outerWidth();
newNode = $(newStage).appendTo(parent);
if (remain.length > 0) {
newNode.html(remain);
}
$(newNode).find('li:first-child').addClass('first-child');
newNode.css({
"position": "absolute",
"left": (width + position.left - 89),
"top": (position.top + 140)
});
var dropArea = $(newNode).find('.ci-droppable');
dropArea.droppable();
dropArea.droppable({
accept: ".ci-draggable",
});
elementSelect(newNode);
};
//staging function//
function staged(event) {
$(".stage:last-child").addClass('staged', function(event) {
appendNewStage();
});
$(".stage").find("li:not('.ui-selected')").remove();
$(".stage").find("li.blank").remove();
$(".stage").removeClass("stage");
}
I triggering the staged function on a button click event. when I give an alert on staged callback it run two times
Upvotes: 0
Views: 124
Reputation: 1074385
In general, jQuery's animation callbacks happen per-element. So if $(".stage:last-child")
matches two elements (because there are two .stage
elements that are the last child in their parent), you'll get two callbacks — one for each element. From the [animate
documentation](
Callback Functions
If supplied, the
start
,step
,progress
,complete
,done
,fail
, andalways
callbacks are called on a per-element basis... If multiple elements are animated, the callback is executed once per matched element, not once for the animation as a whole. Use the.promise()
method to obtain a promise to which you can attach callbacks that fire once for an animated set of any size, including zero elements.
So assuming what you're using plays nicely with jQuery's animation internals (the jQuery UI one does):
$(".stage:last-child").addClass('staged').promise().then(appendNewStage);
Example using jQuery UI's addClass
:
$(".stage:last-child").addClass("staged", function() {
console.log("Callback for " + this.id);
})
.promise().then(function() {
console.log("All done");
});
.staged {
color: blue;
}
<div>
<div id="first" class="stage">
testing 1 2 3
</div>
</div>
<div>
<div id="second" class="stage">
testing 9 8 7
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
(I assume you're using jQuery UI's addClass
addition or something else that adds animation to addClass
. jQuery on its own doesn't animate it, so doesn't have a callback.)
Upvotes: 1