Callback Function Not Working With .Queue() - javascript

I'm trying to run a loop on some images where I change an img's src several times. I want it to loop back through again once it completes so it's a continuous scroll of images. I've set up my function like this:
function img_loop(){
console.log('test');
console.log(this_value.attr('src'));
this_value
.queue(function(next) {
this_value.attr('src',new_img_src); next();
})
.delay(2000)
.queue(function(next) {
this_value.attr('src',new_img_src_2); next();
})
.delay(2000)
.queue(function(next) {
this_value.attr('src',img_src); next();
})
.delay(2000)
.queue(function() {
img_loop();
});
}
img_loop();
It runs successfully once time through. The curious things is that it logs to the console, runs once through and then logs to the console again meaning it's called the function again but I suppose it stops right at the first queue function. I ran a console in that first queue function and can confirm that it doesn't run the second time through.
I'm assuming there is a limitation on using queue() in a callback function? Any ideas on why it wouldn't run again?
EDIT
In reference to the answer below, I tried this with the function having a parameter and then have it loop putting that parameter back in, but unfortunately this did not work:
function img_loop(the_image){
var that = the_image;
console.log(the_image);
the_image
.queue(function(next) {
the_image.attr('src',new_img_src); next();
})
.delay(2000)
.queue(function(next) {
the_image.attr('src',img_src); next();
})
.delay(2000)
.queue(function() {
img_loop(that);
});
}
img_loop(me);
When I log it out in the console, it displays the same content so it retains the value after the loop is run through once. I'm not sure why it doesn't trigger again?
Just showing my progress in case anyone else has ideas?

If when you write this_value you're talking about the this keyword (the context of the function), maybe the value of this is lost in the second call to img_loop.
EDIT
I've been thinking about your code again, in the last .queue call you don't execute the queue, either by calling next() or by calling .dequeue()
I've changed made modifications to the following code, try this one.
function img_loop(the_image){
console.log(the_image);
the_image
.queue(function(next) {
the_image.attr('src',new_img_src); next();
})
.delay(2000)
.queue(function(next) {
the_image.attr('src',new_img_src_2); next();
})
.delay(2000)
.queue(function(next) {
the_image.attr('src',img_src); next();
})
.delay(2000)
.queue(function() {
img_loop.(the_image);
$(this).dequeue();
});
}
img_loop(me);

Related

Unsure on why .load() complete event isn't working

I'm unsure on why this isn't working:
$(document).ready(function() {
setInterval(RefreshDiv, 2000);
})
function RefreshDiv(){
$('#box').load('messages.php #box', function() {
$('#box').on('load', function() {
$('#box').scroll(0, 50);
});
});
}
The tags are correct and the .load() part works every two seconds but I don't understand why my complete event to scroll down 50px isn't working?
I've also tried another method to scroll:
var log = document.querySelector('#box');
log.scrollTop = log.scrollHeight - log.clientHeight;
but this also doesn't execute on load
Edit #1
jQuery($ => {
setInterval(RefreshDiv, 2000);
})
function RefreshDiv() {
$('#box').load('messages.php #box', () => {
$('#box').scrollTop(50);
});
}
The load event only fires on certain elements such as img and the window object. As such I presume #box is not one of them.
You don't actually need the load event handler anyway as the callback itself runs when the load() method completes its request. Try this:
jQuery($ => {
setInterval(RefreshDiv, 2000);
})
function RefreshDiv() {
$('#box').load('messages.php #box', () => {
$('#box').scrollTop(5000);
});
}
It's also worth noting that sending AJAX requests every 2 seconds is not ideal, as it will not scale as you have more concurrent visitors to your site, and can lead to server performance problems. There's likely to be a much better alternative, depending on what it is you're doing.

Modal only triggered after ajax request

I have two questions about this code. The first is why the modal is not shown before the alert? The second is how can i delay the modal, because the popup is so fast that i can't see nothing in the modal.
$('#myModal').modal('hide');
$(document).ajaxStart(function() {
$('#myModal').modal('show');
}).ajaxStop(function() {
$('#myModal').modal('hide');
//$('#myModal').delay(5000).modal('hide'); does not work
});
$(".generate_report").click(function(event) {
event.preventDefault();
$.post("xls.php", $(".form_report").serialize(), function() {
}).done(function(data) {
alert("should be executed only after modal");
});
});
demo
You can achieve the same with this code:
$(".generate_report").click(function (event) {
event.preventDefault();
$('#myModal').modal('show');
setTimeout(function(){
$.post("xls.php", $(".form_report").serialize(),function(data){
$('#myModal').modal('hide');
alert("after modal");
})
}, 2000);
});
And remove this code
$(document).ajaxStart(function() {
$('#myModal').modal('show');
}).ajaxStop(function() {
$('#myModal').modal('hide');
//$('#myModal').delay(5000).modal('hide'); does not work
});
What this code does is show a modal when the ajax call starts and instantly hide it when its done. You can use a timer to wait a while before closing it.
Also you've nested a callback function in your jQuery.post, but you don't use it which causes confusing code here. Theres no need to use .done() when you're just going to append it to the AJAX function directly. You can just use the callback function here.
$.post("xls.php", $(".form_report").serialize(), function(data) {
alert("should be executed only after modal");
});
But that is just a code styling concern. The done(), success(), fail() methods are used on a jQuery.Deferred promise object, which $.ajax happens to return. And since $.post/$.get are just pointers to $.ajax, they will too.
Secondly, if you want the modal to wait before it closes, you can do this:
var waitTimer;
var timeToWait = 2000; // Time to wait here
var $myModal = $('#myModal');
$myModal.modal('hide');
$(document).ajaxStart(function() {
$myModal.modal('show');
}).ajaxStop(function() {
if (waitTimer) {
clearTimeout(waitTimer);
}
waitTimer = setTimeout(function() {
$myModal.modal('hide');
}, msToWait);
});
The .delay() method you tried to use only works after you've animated something.
Also a quick tip: Cache your jQuery selectors. You're telling jQuery to jump in the DOM 3 times to search for the same element.

setTimeout/pausing/ etc

I've tried a few different ways except the right one.
Trying this:
setTimeout( function() {
$('.historyTextBoxes p')
.bind('showText', function(e) {
$(this).fadeIn(800, function(){
$(this).next().length && $(this).next().trigger("showText");
});
}).eq(0).trigger('showText');
}, 4000);
Will wait for 4 seconds, then fade each paragraph in, one after another at the speed of .800 miliseconds.
What I want to do is fade a paragraph in at .800 ms, then wait for 4 seconds before the next paragraph fades in.
The basic set-up of:
$('.historyTextBoxes p')
.bind('showText', function(e) {
$(this).fadeIn(800, function(){
$(this).next().length && $(this).next().trigger("showText");
alert('pause here');
});
}).eq(0).trigger('showText');
works but I've yet to hit the right syntax to make it pause where the alert is.
I tried throwing a call to a function but I don't need to run anything except just to wait.
So in pseudo code, I'm trying to define something like:
function wait() {
pause(for 4 seconds);
}
Then I could just call that function instead of the alert above. My issues with setTimeout has been 'having' to define a function but I'm over thinking something.
Using setTimeout was correct, but you applied it in the wrong place.
$('.historyTextBoxes p').bind('showText',function(e) {
$(this).fadeIn(800,function(){
// this is the callback after the fadein
// here we want to wait (use a timeout)
var next = $(this).next();
if (next.length)
setTimeout(function() {
// before the next text is shown
next.trigger("showText");
}, 4000);
})
}).eq(0).trigger('showText');
This should do it:
function showAll() {
var p = $('.historyTextBoxes p').get(); // array of elements
(function loop() {
if (p.length) {
var el = p.shift();
$(el).fadeIn(800).delay(4000).promise().done(loop);
}
})();
}
demo at http://jsfiddle.net/4dNr3/2/
Note that this uses no explicit timers at all, and nor does it use any events to trigger the next phase - it relies on the animation queue for all timing. Note that it's not generally a good idea to mix timers and animation unless you can guarantee that they're interleaved rather than running in parallel. In this case that's OK, though.

Javascript setTimeout, multiple scripts

I'm having trouble getting a setTimeout to work. I have three js files and I've tried to show the relevant code from them. The setTimeout is in evencard.js. If I remove js-decider.js and load flipcards2.js immediately on page load, the setTimeout works perfectly. However when I set it up as shown below, the setTimeout does not delay anything; The code inside the setTimeout function is ran immediately. Modernizr doesn't seem to be the issue because if I put a setTimeout inside js-decider.js it works.
js-decider.js
$(function() {
$(window).bind('resize', function(){
if (Modernizr.mq("screen and (max-width:680px)")) {
}
else {
$.getScript("js/flipcards2.js");
}
});
});
flipcards2.js
$(function() {
$(".more-images").click(function() {
$(this).addClass("active-more");
});
$('#page .container:odd .more-images').click(function() {
evenCard();
});
});
evencard.js
function evenCard() {
var $thisElse = $('.active-more');
function timeoutTriggerElse() {
$thisElse.closest(".container").removeClass("hide");
}
setTimeout(function(){timeoutTriggerElse()},400);
$('.active-more').removeClass("active-more");
}

Jquery delay not working

Can someone please tell me why my function is not executing, after my images are displayed?
$("#screen").css("background-image", "url('screens/animated/077.gif')").delay(5000).queue(function() {
$("#screen").css("background-image", "url('screens/animated/078.gif')").delay(5000).queue(function() {
buttonClick(16);
});
});
Don't know why it won't call my buttonClick(16); function.
You could just animate instead dude? animate() you can pass a time to and also it has a callback function, so once the first animation is complete you can run more code, i.e.
$(this).animate(function(){
//Do animation
},1000,function(){
//Animation is complete, do something else like the next animation
$(this).animate(function(){
//Another animation to run once the first is complete
});
});
Because you didn't dequeue.
$("#screen").css("background-image", "url('screens/animated/077.gif')").delay(5000).queue(function () {
$(this).css("background-image", "url('screens/animated/078.gif')").delay(5000).queue(function () {
$(this).dequeue();
buttonClick(16);
}).dequeue();
});
The queue function receives a param that you should call when the next function should run.
Example:
$().queue(function (next) {
// Do what you need
next();
});

Categories