I have a button, upon clicking on which a div is shown in 500ms and then after 500ms class shake is added onto that div. This shake classe is then removed after 2 seconds with delay
. What I want is if user keep pressing on button then all callbacks become canceled except the last one.
Problematic code if click is pressed many time:
$("button").click(function() { $(".content").show({ duration: 500, done: function() { $(".content").addClass("shake"); var time = parseFloat($(".content").css("transition-duration")) * 1000; $(".content").delay(time).queue(function() { console.log("shake"); $(".content").removeClass("shake"); $(".content").dequeue(); }); } }) });
div.content { border: 1px solid red; transition: background-color 2s ease-out; background-color: black; display: none; } div.content.shake { background-color: red; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <button>click</button> <div class="content">Content</div>
My solution with clearQueue:
$("button").click(function() { $(".content").show({ duration: 500, done: function() { $(".content").clearQueue(); $(".content").addClass("shake"); var time = parseFloat($(".content").css("transition-duration")) * 1000; $(".content").delay(time).queue(function() { console.log("shake"); $(".content").removeClass("shake"); $(".content").dequeue(); }); } }) });
div.content { border: 1px solid red; transition: background-color 2s ease-out; background-color: black; display: none; } div.content.shake { background-color: red; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <button>click</button> <div class="content">Content</div>
But this method never lets the shake
class to be added. Because the queue mentioned after clearQueue
is also cleared.
How can I prevent clearQueue() from clearing in-future queues? And why does clearQueue()
behave this way? How does it know what queue
would be added in future?
2 Answers
Answers 1
Provide a name for the .delay()
and .queue()
calls. Check if .content
.queue(queueName)
has a .length
before setting .delay(time, queueName)
. Chain .dequeue(queueName)
to .queue(queueName)
call instead of calling .dequeue()
within .queue()
function. Note that .delay()
also adds a function to element .queue()
array
$("button").click(function() { $(".content").show({ duration: 500, done: function() { $(".content").clearQueue(); $(".content").addClass("shake"); var time = parseFloat($(".content").css("transition-duration")) * 1000; if (!$(".content").queue("shake").length) $(".content").delay(time, "shake").queue("shake", function() { console.log("shake"); $(".content").removeClass("shake"); }).dequeue("shake"); } }) });
div.content { border: 1px solid red; transition: background-color 2s ease-out; background-color: black; display: none; } div.content.shake { background-color: red; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <button>click</button> <div class="content">Content</div>
Answers 2
Note: this solution uses a different method than clearQueue()
.
As mentioned in the comments, there might be better options for achieving the effect you want. It sounds like you're trying to keep the shake
class enabled for X seconds after the last button press.
We can accomplish this with setTimeout()
, which executes a function after a specified amount of time. In this cause, we'll have our setTimeout()
callback function remove the .shake
class after time
seconds.
To keep the .shake
class enabled when the button is clicked we only need to 'reset' the setTimeout
function. We can do this by clearing the timeout, using clearTimeout
, then recreating it. This is accomplished by assigning the setTimeout
function to a variable, which we pass to clearTimeout
to clear it, then recreate the timeout.
The effect will be that the function to remove the .shake
class will run time
seconds AFTER the last time the button is clicked.
var remover; $("button").click(function() { $(".content").show({ duration: 500, done: function() { if (remover) { clearTimeout(remover); } $(".content").addClass("shake"); var time = parseFloat($(".content").css("transition-duration")) * 1000; remover = window.setTimeout(function(){ console.log("removing shake"); $(".content").removeClass("shake"); }, time) } }) });
div.content { border: 1px solid red; transition: background-color 2s ease-out; background-color: black; display: none; } div.content.shake { background-color: red; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <button>click</button> <div class="content">Content</div>
0 comments:
Post a Comment