Execute function after async function is done - javascript

How to make function extra_stuff to be executed after anim or display_effects functions are done ? Best option would be to hold function extra_stuff until animate is done because i don't want to edit anonymous function passed to on method, it should stay simple and readable.
<html>
<head>
<meta charset="utf-8">
<script src="jquery-2.0.3.min.js"></script>
<style>
.selected {color:pink;}
</style>
</head>
<body>
<ul id="workers">
<li>worker#1</li>
<li>worker#2</li>
<li>worker#3</li>
<li>worker#4</li>
</ul>
<script>
$(function()
{
function unmark_selected()
{
$('.selected').removeClass('selected');
}
function mark_user(e)
{
e.addClass('selected');
}
function display_effects(e)
{
e.animate({ fontSize: "24px" }, 1500);
}
function extra_stuff()
{
console.log('maybe another animation');
}
$('ul#workers li a').on('click', function()
{
unmark_selected();
mark_user( $(this) );
display_effects( $(this) );
extra_stuff();
});
});
</script>
</body>
</html>

Make display_effects to return a promise() object, and then call the extra_stuff method in the done callback of the promise
$(function () {
function unmark_selected() {
$('.selected').removeClass('selected');
}
function mark_user(e) {
e.addClass('selected');
}
function display_effects(e) {
return e.animate({
fontSize: "24px"
}, 1500).promise();
}
function extra_stuff() {
console.log('maybe another animation');
}
$('ul#workers li a').on('click', function () {
unmark_selected();
mark_user($(this));
display_effects($(this)).done(extra_stuff);
});
});

You need a callback:
function display_effects(e, callback) {
e.animate({ fontSize: "24px" }, 1500, callback);
}
$('ul#workers li a').on('click', function() {
unmark_selected();
mark_user( $(this) );
display_effects( $(this), extra_stuff ); // no invocation, pass reference!
});
It will be called in the future, when the fontsize animation is done. Check the docs for the .animate() method. Notice that if you simply want to add another animation after the fontsize, they will be queued automatically.

Related

jQuery fix click memorising

$(".fsb").on("click", function () {
if ($('.fsb').hasClass('fsbc')) {
$('#sfo p').fadeIn(500);
setTimeout(function () {
$('#sfo p').fadeOut(500);
}, 500);
} else {
$('#sfof p').fadeIn(500);
setTimeout(function () {
$('#sfof p').fadeOut(500);
}, 500);
}
});
After clicking many times on the button(fast), it will repeat hiding and unhiding that much times. I want to disable that but have no ideas.(sorry, I'm new to this).
jQuery allows to use .fadeIn() and .fadeOut() in chain without setTimeout().
To remove all queued animation place .stop(true) before them.
Inside the event handler, you can use $(this) to work on the clicked element.
$(document).ready(function() {
$(".fsb").on("click", function() {
if ($(this).hasClass('fsbc')) {
$('#sfo p').stop(true).fadeIn(500).fadeOut(500);
} else {
$('#sfof p').stop(true).fadeIn(500).fadeOut(500);
}
});
});
.hide-p p {
display: none;
}
<button class="fsb fsbc">Click SFO</button>
<button class="fsb">Click SFOF</button>
<div id="sfo" class="hide-p">
<p>SFO</p>
</div>
<div id="sfof" class="hide-p">
<p>SFOF</p>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

mouseIsOver() is not working

I want to change margin of one tag when mouse is hovered on its parent.
mouseIsOver() method doesn't making any change.
function der(){
if($(".experience-div li").mouseIsOver()){
$(".star").css('margin-right','10px');
}
}
der();
I changed it to is() method, still nothing has changed.
>
function der(){
if($(".experience-div li").is(":hover")){
$(".star").css('margin-right','10px');
}
}
der();
There is no mouseIsOver function in jQuery or the DOM.
You can use jQuery's hover:
function der(){
$(".experience-div li").hover(
function() {
$(".star").css('margin-right','10px');
},
function() {
$(".star").css('margin-right','auto'); // Or whatever it should be when not hovered
}
);
}
der();
I wouldn't recommend manipulating the style directly like that, though, I'd use a class:
function der(){
$(".experience-div li").hover(
function() {
$(".star").addClass('hovered');
},
function() {
$(".star").removeClass('hovered')
}
);
}
der();
With
.star.hovered {
margin-right: 10px;
}
Live Example:
function der() {
$(".experience-div li").hover(
function() {
$(".star").addClass('hovered');
},
function() {
$(".star").removeClass('hovered')
}
);
}
der();
.star.hovered {
margin-right: 10px;
color: red;
}
<div class="star">I'm the star</div>
<div class="experience-div">
<ul>
<li>Hover me</li>
</ul>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
To listen to events (such as mouseover) in jQuery you need to use the .on function:
$(".experience-div")
.on('mouseenter', 'li', function () {
$(".star").css('margin-right', '10px');
})
.on('mouseleave', 'li', function () {
$(".star").css('margin-right', '0');
});
You don't need to use JS to complete this. you simply need to add a :hover state to the class in question.

how to make jquery infinite loop

this is my jquery code.this code contain three functions.this three function repeatedly execute for looping.but this code not run properly.how to make recursive call with three functions.the pid1,pid2,pid3 is paragraph tag id's.this code used to make text animation.
$(document).ready(function(){
function animate()
{
$('#pid1').fadeOut(3000, function()
{
$(this).text('string1').fadeIn(3000);
});
animate1();
}
function animate1()
{
$('#pid2').fadeOut(3000, function()
{
$(this).text('string2').fadeIn(3000);
});
animate2();
}
function animate2()
{
$('#pid3').fadeOut(3000, function()
{
$(this).text('string3').fadeIn(3000);
});
animate();
}
});
try like this :
$(document).ready(function(){
function animate() {
$.when($('#pid1').fadeOut(3000, function() {
$(this).text('string1').fadeIn(3000);
})).then(function() {
animate1();
});
}
function animate1() {
$.when($('#pid2').fadeOut(3000, function() {
$(this).text('string2').fadeIn(3000);
})).then(function() {
animate2();
});
}
function animate2() {
$.when($('#pid3').fadeOut(3000, function() {
$(this).text('string3').fadeIn(3000);
})).then(function() {
animate();
});
}
animate();
});
Here a jsFiddle : http://jsfiddle.net/Pascalz/CNRSd/
You must call the function again after making sure that element has fadeout. You should use fadeout callback functions
change you function like this:
function animate()
{
$('#pid1').fadeOut(3000, function()
{
$(this).text('string1').fadeIn(3000, function(){animate(); });
});
}
Here is the link of jsbin by using callback functions
animate by using callback

Using setTimeout to delay timing of jQuery actions

I am attempting to delay the swapping of text in a div. It should operate like a slider/carousel for text.
I must have the code wrong, as the final text replacement never happens.
Also, how would I animate introducing the replacement text (window blinds, for eg.)?
<html>
<head>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js"></script>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.9.1/themes/base/jquery-ui.css" />
<script type="text/javascript">
$(document).ready(function() {
$("#showDiv").click(function() {
$('#theDiv').show(1000, function() {
setTimeout(function() {
$('#theDiv').html('Here is some replacement text', function() {
setTimeout(function() {
$('#theDiv').html('More replacement text goes here');
}, 2500);
});
}, 2500);
});
}); //click function ends
}); //END $(document).ready()
</script>
</head>
<body>
Below me is a DIV called "theDiv".<br><br>
<div id="theDiv" style="background-color:yellow;display:none;width:30%;margin:0 auto;">
This text is inside the Div called "theDiv".
</div><br>
<br>
<input type="button" id="showDiv" value="Show DIV">
</body>
</html>
.html() only takes a string OR a function as an argument, not both. Try this:
$("#showDiv").click(function () {
$('#theDiv').show(1000, function () {
setTimeout(function () {
$('#theDiv').html(function () {
setTimeout(function () {
$('#theDiv').html('Here is some replacement text');
}, 0);
setTimeout(function () {
$('#theDiv').html('More replacement text goes here');
}, 2500);
});
}, 2500);
});
}); //click function ends
jsFiddle example
Try this:
function explode(){
alert("Boom!");
}
setTimeout(explode, 2000);
You can also use jQuery's delay() method instead of setTimeout(). It'll give you much more readable code. Here's an example from the docs:
$( "#foo" ).slideUp( 300 ).delay( 800 ).fadeIn( 400 );
The only limitation (that I'm aware of) is that it doesn't give you a way to clear the timeout. If you need to do that then you're better off sticking with all the nested callbacks that setTimeout thrusts upon you.
This is how I solved the problem
The menu closes a few seconds after mouse out (that if hover didn't fire),
//Set timer switch
$setM_swith=0;
$(function(){
$(".navbar-nav li a").click(function(event) {
if (!$(this).parent().hasClass('dropdown'))
$(".navbar-collapse").collapse('hide');
});
$(".navbar-collapse").mouseleave(function(){
$setM_swith=1;
setTimeout(function(){
if($setM_swith==1) {
$(".navbar-collapse").collapse('hide');
$setM_swith=0;}
}, 3000);
});
$(".navbar-collapse").mouseover(function() {
$setM_swith=0;
});
});

Why is this wrong? (use of "this" with jQuery)

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.js"></script>
<script type="text/javascript">
function bigtosmalltriangle() {
$(this).siblings("div.break").removeClass('triangle3').addClass('triangle1');
setTimeout ( "smalltomediumtriangle()", 400 );
}
function smalltomediumtriangle() {
$(this).siblings("div.break").removeClass('triangle1').addClass('triangle2');
setTimeout ( "mediumtobigtriangle()", 400 );
}
function mediumtobigtriangle() {
$(this).siblings("div.break").removeClass('triangle2').addClass('triangle3');
setTimeout ( "bigtosmalltriangle()", 400 );
}
$(function() {
$("span#clickhere").click(
function() {
/* do a lot stuff here */ bigtosmalltriangle();
$(this).hide();
}
);
});
</script>
<style type="text/css">
.triangle1 {background:#000;}
.triangle2 {background:red;}
.triangle3 {background:white;}
</style>
<div><div class="break">Hello World</div><span id="clickhere">asdf</span></div>
I'm trying to get get the div.break to scroll through 3 bgcolors, but when I click on the span it has no effect. Does anyone know what I should do?
Thanks.
You want to call your functions with a specific "this". I asked a similar question: Call function with "this".
$(function() {
$("span#clickhere").click(
function() {
/* do a lot stuff here */
bigtosmalltriangle.call(this);
$(this).hide();
}
);
});
I think because of closures (see Matthew Crumley's answer) the callback functions themselves don't need to be modified, because setTimeout keeps the "scope." I don't know Javascript enough to remotely guarantee that, though. If I am wrong, simply perform the .call(this) trick for the callback functions as well.
The problem is that "this" is not bound to the span you clicked on in the bigtosmalltriangle, smalltomediumtriangle, and mediumtobigtriangle functions. You need to either pass in the element as a parameter, or set a variable that's in scope in all the functions through closures.
Parameter passing:
function bigtosmalltriangle(elements) {
elements.removeClass('triangle3').addClass('triangle1');
setTimeout(function() { smalltomediumtriangle(elements); }, 400);
}
function smalltomediumtriangle(elements) {
elements.removeClass('triangle1').addClass('triangle2');
setTimeout(function() { mediumtobigtriangle(elements); }, 400);
}
function mediumtobigtriangle(elements) {
elements.removeClass('triangle2').addClass('triangle3');
setTimeout(function() { bigtosmalltriangle(elements); }, 400);
}
$(function() {
$("span#clickhere").click(
function() {
/* do a lot stuff here */
bigtosmalltriangle($(this).siblings("div.break"));
$(this).hide();
}
);
});
Closures:
$(function() {
$("span#clickhere").click(
function() {
var elements = $(this).siblings("div.break");
function bigtosmalltriangle() {
elements.removeClass('triangle3').addClass('triangle1');
setTimeout(smalltomediumtriangle, 400);
}
function smalltomediumtriangle() {
elements.removeClass('triangle1').addClass('triangle2');
setTimeout(mediumtobigtriangle, 400);
}
function mediumtobigtriangle() {
elements.removeClass('triangle2').addClass('triangle3');
setTimeout(bigtosmalltriangle, 400);
}
/* do a lot stuff here */
bigtosmalltriangle();
$(this).hide();
}
);
});

Categories