i use lab.js 2.0.3 for parallel loading my scripts.
the problem is, that in 1 of 10 times the "$(window).load" part fired much too early. the part with "$(document).ready" works fine.
example:
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/1.7.2/jquery.min.js" type="text/javascript"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/labjs/2.0.3/LAB.min.js" type="text/javascript"></script>
<script>
$LAB
.script("script1.js")
.script("script2.js")
.script("script3.js")
.wait(function(){
$(window).load(function() {
// Function 1
$("jQuery Function 1");
// Function 2
$("jQuery Function 2");
});
$(document).ready(function() {
// Function 3
$("jQuery Function 3");
// Function 4
$("jQuery Function 4");
});
});
</script>
i guess, that i do something wrong, but don't know what : (
This may be because $(window).load() only ever fires once per page. If you missed it waiting on the scripts to load, you missed it. So, between .wait and .load, you have a race condition that's not really predictable whether you'll win or lose.
$(document).ready(), on the other hand, is similar to Deferred Objects in that new callbacks can be added after the event has fired and will still be called.
You can see this demonstrated here: http://jsfiddle.net/coiscir/AFszS/1/
$(window).load(function () {
console.log('outer window.load');
// bind after the event
setTimeout(function () {
$(window).load(function () {
console.log('inner window.load'); // you'll never see this
});
}, 10);
});
If you want a similar effect as .ready for .load, you can use a Deferred Object to mediate between the actual event and your callbacks: http://jsfiddle.net/coiscir/m4D46/
var windowLoad = $.Deferred();
$(window).load(windowLoad.resolve);
$LAB
.script("script1.js")
.script("script2.js")
.script("script3.js")
.wait(function(){
windowLoad.done(function() {
// Function 1
$("jQuery Function 1");
// Function 2
$("jQuery Function 2");
});
$(document).ready(function() {
// Function 3
$("jQuery Function 3");
// Function 4
$("jQuery Function 4");
});
});
Related
I thought this is something easy to do but I dont find anything helping me out of this.
I have a function
(function($){
myFunction = function(e){
e.preventDefault();
// do stuff
// load ajax content
// animate and show
}
$('.button').on( 'click', myFunction);
})(jQuery);
now this works but I need to know, wait untill everything is done if someone presses many .buttons in a short time cause there are a few elements with class button
I've tried with promise()
$('.button').on( 'click', function(){
$.when( myFunction() ).done(function() {
alert('finished')
});
});
but that gives me an error e is undefined and
$('.button').on( 'click', myFunction).promise().done(function() {
alert('finisehd');
});
anyone knowing what I'm doing wrong and how I could do it to get it to work?
The most common solution would be to set a variable inside the click handler when myFunction is called and check its state with every call of the click handler.
This could be done somewhere along the lines of this:
(function($){
var wait = false;
myFunction = function(e){
e.preventDefault();
if (wait) {
return;
}
wait = true;
// ...
wait = false;
}
$('.button').on( 'click', myFunction);
})(jQuery);
Your function myFunction expects one argument, when you call myFunction() the argument is missing.
Not tested but it should works:
$('.button').on( 'click', function(e){
$.when( myFunction(e) ).done(function() {
alert('finished')
});
});
In addition to not passing in the e variable. You're using $.when incorrectly.
If you want to have the done function called after myFunction finishes its ajax call. You'll need to return a promise from myFunction.
function myFunction(e) {
return $.Deferred(function(deferred) {
doAjax(function(content) { // callback
deferred.resolve(content);
});
});
}
Now when you do
// inside event handler
$.when(myFunction(e)).done(function(content) {
// whoo!
});
if i do:
method();
method();
both calls will run in parallel (at same time)
i just would like to make the second method(); wait until the first method(); is finished before to start, and do it dynamically cause i can't know how many times i will launch method(); at same time .
Is it possible?
just for example, those runs at same time as i can see... http://jsfiddle.net/Lcgb8/
You could use then if you return a Deferred.
E.g.
function method() {
var d = $.Deferred();
//do something async
setTimeout(function () {
d.resolve('some data'); //inform listeners that the process is completed
}, 2000);
return d; //return the deferred object
}
Then you could do:
method().then(method).then(method).then(method);
Note that the return value of each call will be passed as first argument to the next call, respectively.
EDIT: Here's an example on how you could queue the async operations dynamically.
FIDDLE
function changeColorAsync(color) {
var d = $.Deferred();
setTimeout(function () {
$('body').css('background', color);
d.resolve();
}, 4000);
return d;
}
$(function () {
$('#color-form').on('submit', function (e) {
var color = $(this).find(':checked').val(), d;
d = d?
d.then(changeColorAsync.bind(this, color)) :
changeColorAsync(color);
return false;
});
});
Here is a sequentially animation using transitionend
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>animation</title>
<style>
div{
width:50px;height:50px;background-color:#093;
-webkit-transition:all 300ms ease;
}
div.move{-webkit-transform:translate3d(200px,0,0);}/*GPU HW acceleration*/
</style>
<script>
(function(W){
var D,d,L,c=0;
function init(){
D=W.document;d=D.getElementsByTagName('div');L=d.length;var l=d.length;
while(l--){d[l].addEventListener('transitionend',next,false)}
next();
}
function next(){
d[c].classList[(d[c].className=='move'?'remove':'add')]('move');
c++;c=(c==L?0:c);
}
W.addEventListener('load',init,false);
})(window)
</script>
</head>
<body><div></div><div></div><div></div><div></div></body>
</html>
it had little error fixed now..
supports infinite div's and it's infinite loop using low resources. =)
your method() would be my next()
if someone want's to jsfiddle it... i don't use that.
ps.: pure javascript (no jquery) + css3 (with -webkit prefix);
example
http://jsfiddle.net/4eujG/
Have a look at jQuery.queue().
Using callback:
var test = function (letter, callback) {
console.log(letter);
if (typeof callback !== 'undefined') {
callback();
}
};
Now you can run it:
test('a', function () {
test('b', function () {
test('c')
});
});
The result in console is:
a
b
c
Is it helpful to you?
$( "div" ).promise().done(function() {
$( "p" ).append( " Finished! " );
});
Hope this example must have cleared your query
LIVE DEMO
Javascript, and most other languages, run code sequentially.
Therefore, they will not both run at the same time.
In fact, it is not possible to run two different pieces of Javascript code at the same time. However, in many other languages, it is possible using threads.
However, if they make AJAX calls, the corresponding server-side code called by both functions will run simultaneously.
To prevent that, you'll need to make the first function accept a callback parameter and pass it the second function.
I have some code in the - $(document).ready(function(){ - that shuffles stuff around, the code is fired when the page is loaded but what I want to do is add a button so this function runs every time I press the button, how could I achieve this, thanks??
function shuffleStuffAround() {
// truffle shuffle
}
$(function($) { // DOM ready
shuffleStuffAround();
$("#some-button").click(function() {
shuffleStuffAround();
return false; // you probably want this
});
});
You can save you "shuffle stuff around" code as a function and call it from other parts of your codebase.
var foo = function() {
// code that shuffles stuff around
};
$(document).ready(function() {
foo();
// other stuff
});
$('#mybutton').click(foo);
//or
$('#mybutton').click(function() {
foo();
// other stuff.
});
You could simple refactor the code that you run on the ready function into its own function and call that in your button's click event:
$(document).ready(function(){
codeToRun();
$('.button').click(function(){codeToRun()});
});
function codeToRun(){
// do work
}
Via PHP, i'm generating some JavaScript code, witch looks like this:
<script type="text/javascript">
$(window).load(function() {
maps.showUsers('Odenthal, Germany',1);
maps.putCenter(51.1833,7.2);
});
</script>
I have to be sure, that the first line is executed before the second line. This works fine in IE and FF, but not in Chrome. How can i control it?
try callbacks:
$(window).load(function() {
maps.showUsers('Odenthal, Germany',1, function(){
maps.putCenter(51.1833,7.2);
});
});
you have to use that callback at the end of your function:
function showUsers(a, b, c, callback) {
...
if(typeof callback == 'function')
callback.call();
}
Try this with some delay. You can set the appropriate delay as per your need.
$(window).load(function() {
maps.showUsers('Odenthal, Germany',1);
setTimeout(function(){
maps.putCenter(51.1833,7.2);
}, 400);
});
how to execute jquery code one by one?
I want first do "function 1", when finish the job. then do "function 2"...
Thanks.
<script type="text/javascript">
jQuery(document).ready(function(){
$(document).ready(function(){
//function 2, jqeury.ajax
});
$(document).ready(function(){
//function 3, jqeury.json
});
$('#col').load("home.html");
//function 4, jqeury.load
});
});
</script>
<script type="text/javascript">
jQuery(document).ready(function(){
//function 1, a jquery slider plungin
});
</script>
You don't need so many document ready calls. One will suffice
If you mean you want to call each method after one has received the response from the AJAX calls you are making, put the code in the callback;
$(document).ready(function(){
one(); //call the initial method
});
function one(){
$.get('url', {}, function(data){
two(); //call two() on callback
})
}
function two(){
$.getJSON('url', {}, function(data){
three(); //ditto
})
}
function three(){
$('#selector').load('url');
}
The docs
http://api.jquery.com/jQuery.get/
http://api.jquery.com/jQuery.getJSON/
http://api.jquery.com/load/
Instead of using more than one document.ready() use callback functions as below.
<script type="text/javascript">
function ajaxfun() {
//function 2, jqeury.ajax
//in ajax callback call the jsonfun();
}
function jsonfun(){
//function 3, jqeury.json
//after json function add the next function in it callback.
}
</script>
<script type="text/javascript">
jQuery(document).ready(function(){
//function 1, a jquery slider plungin
//Call ajaxfun() here to execute second.
});
</script>
It looks like you are doing three ajax calls. Since jQuery 1.5, we now have a Deferred object (technically a jqXHR object) returned from ajax calls, so you can chain them like this:
$(function() { // this is a document ready function. it's all you need.
$.ajax(/* your ajax specs */).done(function() {
$.getJSON('somepath').done(function() {
$('#container').load('etc.');
});
});
});
use setTimeout function
function f1(para) {
// ...
// do work;
setTimeout(f2, 10);
}
function f2() {
// ...
// do work
setTimeout(f3, 10);
}
<script type="text/javascript">
jQuery(document).ready(function(){
function2(){ //declare what function 2 will do here
//function 2, jqeury.ajax
}
function3(){
//function 3, jqeury.json
}
$('#col').load("home.html");
//function 4, jqeury.load
});
});
</script>
<script type="text/javascript">
jQuery(document).ready(function(){
//function 1, a jquery slider plungin
function2(); // execute function 2 after 1
function3();
});
</script>