How can I delay document.ready until a variable is set? - javascript

I am doing QUnit testing in an IFRAME and have a recursive JavaScript function that loads all of the scripts from the parent page into the IFRAME before starting QUnit. This works great. My problem is that some of our scripts use document.ready to make stuff start.
Something such as:
$(document).ready(function () {
// blah
});
to do do their work. I'd prefer to not change production code just to account for tests and I don't want these production scripts to think the IFRAME document is "ready" until every scripts is loaded.
How I can delay "document.ready" itself?
Here is my pseudocode to give you an example to work from:
scripts[0] = "/foo/bar.js";
scripts[1] = "/blah/blah.js";
function RecursiveScriptStart(){
// I want to set document.ready = false right here!
if(scripts.length == 0) {
QUnitStart();
return;
}
RecursiveScriptLoader(0, scripts);
}
function RecursiveScriptLoader(currentScriptID, scripts) {
$.getScript(scripts[currentScriptID], function () {
if (currentScriptID == (scripts.length - 1)) {
QUnitStart();
}
else {
RecursiveScriptLoader(currentScriptID + 1, scripts);
}
});
}
function QUnitStart() {
// I want to set document.ready = true right here!
QUnit.stop();
QUnit.start();
}
The actual code is similar, but involves a jquery selector populating the array "scripts[]" with JavaScript tag "src" properties.
Thanks!

If you're using jQuery 1.6+ then you can use holdReady. Just set $.holdReady(true) at the top of your script and then in the beginning of QUnitStart set $.holdReady(false).

This code worked for me; To invoke $(window).load() inside $(document).ready()
$(document).ready(function() {
$(window).load(function() {
// this code will run after all other $(document).ready() scripts
// have completely finished, AND all page elements are fully loaded.
});
});
This method would preserve execution order in all cases by making sure that your run-last code is not passed to $(window).load() until all $(document).ready() scripts have completed.

If your using jQuery 1.6 or higher you can use holdReady to delay the ready event being fired.
For 1.4.3 or higher you can use $.readyWait property to delay the ready event, Demo Here (not my code)
if your interested in figuring out how jquery handles the ready event search for the line
jQuery( document ).trigger( "ready" ).unbind( "ready" );
in your developer copy of jquery.js

Just to fill in where others left off, you may use this load order in your test.html
<script src="jquery.js"></script>
<script src="qunit.js"></script>
<script>$.holdReady(true);</script>
<script src="theThingIwantToTest.js"></script>
<script src="theTestScript.js"></script>

<html lang="en">
<head>
<meta charset="utf-8">
<script type="text/javascript">
window.setInterval(function() {
console.log(document.getElementById('waitForMe'));
}, 500);
</script>
</head>
<body>
Before
<script type="text/javascript" src="/php-with-sleep.php"></script>
After
<div id="waitForMe"></div>
</body>
</html>
Extended test, I have tested RequireJs domReady plugin
<html lang="en">
<head>
<meta charset="utf-8">
<script type="text/javascript" src="/vendor/require/require.js"></script>
<script type="text/javascript">
window.setInterval(function() {
console.log(document.getElementById('waitForMe'));
}, 500);
require.config({
baseUrl: '/',
paths: {
domReady: 'vendor/require/plugin/dom-ready',
jQuery: 'vendor/jquery'
},
shim: {
async: {
exports: 'async'
},
jQuery: {
exports: 'jQuery'
}
}
});
require(['domReady', 'jQuery'], function(domReady, $) {
console.log('jQuery loaded');
$(function() {
console.log('jQuery dom ready');
});
domReady(function() {
console.log('domReady requireJs plugin, callback');
})
});
require(['domReady!', 'jQuery'], function(domReady, $) {
console.log('domReady! (no callback)');
});
require(['domReady', 'jQuery'], function(domReady, $) {
console.log('domReady plugin loaded');
});
</script>
</head>
<body>
Before
<script type="text/javascript" src="/php-with-sleep.php"></script>
After
<div id="waitForMe"></div>
</body>
</html>

Related

Conflicting jquery versions won't work even with $.noConflict(true);

My html file has various functions which requires two different jquery versions. In the head section I have them loaded like this:
<script type="text/javascript" src="http://code.jquery.com/jquery-1.6.min.js"></script>
<script type="text/javascript">
var $jq16 = $.noConflict(true);
</script>
<script src="http://code.jquery.com/jquery-2.1.0.min.js"></script>
<script type="text/javascript">
var $jq21 = $.noConflict(true);
</script>
I mostly need to use jquery-2.1.0.min.js so in all my scripts I've replaced every single $ with $jq21.
For instance, if I ony include jquery-2.1.0 in my page and leave out v1.6, then the following script works fine. But when I include v1.6, and switch $ to $jq21, and also include the noConflict code, this script doesn't work:
<script>
$jq21('#form-signup_v1').validate({
submit: {
settings: {
inputContainer: '.field'
},
callback: {
onBeforeSubmit: function (node) {
myBeforeSubmitFunction(':D', ':)', node);
},
onSubmit: function (node) {
console.log('#' + node.id + ' has a submit override.');
//node.submit();
}
}
},
debug: true
});
function myBeforeSubmitFunction(a, b, node) {
document.getElementById("form-signup_v1").submit();
console.log(a, b);
$jq21(node).find('input:not([type="submit"]), select, textarea').attr('readonly', 'true');
$jq21(node).append('<div class="ui active loader"></div>');
}
</script>
Every $ on the page is switched to $jq21 and the scripts won't work.
Any ideas? Thank you.

$(document).ready(function () { ... won't fire

I have the following code at the end of one of my Views:
#section Scripts {
<script type="text/JavaScript">
$(document).ready(function () {
alert("!!!");
});
</script>
}
What ever I do, I can't get it to fire. I have checked and further up in the code JQuery is included. Using the suggestion here I changed my code to the following to confirm that jquery was correctly loaded. This gives the 'Yeah!' alert when loading the page.
#section Scripts {
<script type="text/JavaScript">
window.onload = function () {
if (window.jQuery) {
// jQuery is loaded
alert("Yeah!");
} else {
// jQuery is not loaded
alert("Doesn't Work");
}
}
</script>
}
The end of the source in my page looks like:
<script src="/Scripts/jquery-1.9.1.js"></script>
<script src="/Scripts/jquery-ui-1.8.24.js"></script>
<script src="/Scripts/bootstrap.js"></script>
<script src="/Scripts/breakpoints.js"></script>
<script src="/Plugins/jquery-unveil/jquery.unveil.js"></script>
<script src="/Plugins/jquery-fademenu/jquery.fademenu.js"></script>
<script src="/Plugins/jquery-block-ui/jqueryblockui.js"></script>
<script src="/Plugins/jquery-slimscroll/jquery.slimscroll.js"></script>
<script src="/Plugins/bootstrap-select2/select2.js"></script>
<script src="/Plugins/bootstrap-datepicker/js/bootstrap-datepicker.js"></script>
<script src="/Plugins/dropzone/dropzone.js"></script>
<script src="/Scripts/core.js"></script>
<script type="text/JavaScript">
$(document).ready(function () {
alert("!!!");
});
</script>
<!-- Visual Studio Browser Link -->
<script type="application/json" id="__browserLink_initializationData">
{"appName":"Chrome","requestId":"6301d560dc274f4ea5ec24b8e0c2a19f"}
</script>
<script type="text/javascript" src="http://localhost:50280/1cd42285f06243669b1fd5837f1f05c3/browserLink" async="async"></script>
<!-- End Browser Link -->
</body>
</html>
I can't work out where I am going wrong...
if this coode works properly
window.onload = function () {
if (window.jQuery) {
// jQuery is loaded
alert("Yeah!");
} else {
// jQuery is not loaded
alert("Doesn't Work");
}
}
and this code doesn't :
$(document).ready(function () {
alert("!!!");
});
your likely problem is that there is a conflict with the dollar sign $
I would type out jQuery instead of using the dollar sign , or of course you can do something like this:
var j = jQuery.noConflict();
then you can do use the j where you used to use $
OR... there is simply just an error in the console that you still have not responded about , if that is the case I will update answer
EDIT::
The reasons that you code was not executing was because javascript is weird in the sense that if there is an error anywhere in the block of javascript code then nothing below it will be executed. That is why I asked if there were any console error's. Checking the console is the first step to solving any javascript error.
remove #section Scripts block put script block only and try... if not then remove all js use only jquery and try it will definatly. now add one by one script and find one which is conflicting. .

Structure of JavaScript files and Modernizr/yepnope

I'm looking into the whole asynchronous script loading thing with Modernizr and yepnope.js and I'm wondering how I can adapt my application's structure to use asynchronous script loading.
Right now the structure resembles this:
...
<head>
<script src=jquery.js></script>
<script src=plugin1.js></script>
<script src=plugin2.js></script>
<script src=plugin3.js></script>
<script src=global.js></script>
</head>
<body>
This code is found in a header.php file that is required throughout the application. In the document body section (other PHP files), I may have some JavaScript files like this:
...
<script src=moduleA.js></script>
<script src=someScripts.js></script>
</html>
Here's a simplified example of what moduleA.js and someScripts.js could contain:
$(document).ready(function() {
$('.searchDate').myCoolPlugin({ /* some options */ });
});
And someScripts.js:
$(document).ready(function() {
$('#departureDate, #arrivalDate').myCoolPlugin({ /* some options */ });
});
If I'm using Modernizr, at the top of the page I would remove the other plugin scripts and in global.js I'd write:
Modernizr.load([
{
test: $.fn.myCoolPlugin,
nope: 'plugin1.js',
complete: function() {
$(document).ready(function() {
$('.filterDates').myCoolPlugin();
}
}
}
]);
How do I guarantee that myCoolPlugin has been loaded by the time moduleA.js and someScripts.js are executed? I realize that I can wrap the plugin initialization in those files with Modernizr.load(), but that seems like unnecessary duplication of code.
If I have understood your question correctly then you want to execute the body scripts after the necessary scripts have been loaded with Modernizr.
You could do something like this:
// Header script
var race_won = false;
var load_body_script = function() {
race_won = true;
};
Modernizr.load([
{
test: ..your condition..,
yep: ..test success..,
nope: ..test fail..,
complete: function() {
$(document).ready(function() {
$('.filterDates').myCoolPlugin();
load_body_script();
}
}
}
]);
// Body script
var body_script = function() {
// .. your code here ..
}
if (race_won) {
body_script();
}
else {
load_body_script = body_script;
}

Why does this super simple jquery not work?

I'm having hard time getting this snippet to work. I have made a minimal example. You can view it online: http://jsfiddle.net/qnnZe/ where it is working!
test.html
<!DOCTYPE html>
<head>
<title>test</title>
<meta charset="utf-8">
<script src="jquery.min.js"></script>
<script src="test.js"></script>
</head>
<body>
<p>I am going to test right now.</p>
</body>
</html>
test.js
$("p").click(function () {
$(this).hide("slow");
});
However, on my server it does not work. Here is the link to my server: http://techinf.de/sleepytime/test.html
As always, any help appreciated.
Because in jsFiddle your script code is executed after the DOM has loaded (that's the default option, see the dropdown set to "onDomReady"), on your page it's executed before that. It would work if you wrap your code in a ready() handler:
$(function()
{
$("p").click(function () {
$(this).hide("slow");
});
});
You need to wrap your click handler in a document ready function.
Try either:
$(document).ready(function () {
$("p").click(function () {
$(this).hide("slow");
});
});
or
$(function () {
$("p").click(function () {
$(this).hide("slow");
});
});
It will execute before the DOM is ready. Click handlers should be added in any of the normal jQuery "ready" methods, like:
$(function() {
$("p").click(function () {
$(this).hide("slow");
});
});

jquery load() after ajax page is loaded - howto

i have following lines included at the bottom of my index.php:
<script type="text/javascript" language="javascript" src="class/jquery-1.4.3.min.js"> </script>
<script type="text/javascript" language="javascript" src="class/jquery.nivo.slider.pack.js"></script>
<script type='text/javascript' language='javascript'>
$(window).load(function() {
$('#slider').nivoSlider();
});
</script>
problem lies in $(window).load ...
index.php's body is updated onload through ajax call which delivers div#slider upon matching. this makes it nivoSlider() not executing. do you have any trick to make this thing work. i do prefer non-jquery way around it, but at the end of the day anything helps.
many thanks
WEBPAGE IS HERE
Add the call in the callback for the AJAX load.
$('.something').load( 'http://www.example.com/foo', function() {
$(this).find('#slider').nivoSlider();
});
Example using your code (for body):
$(function() { // run on document ready, not window load
$('#content').load( 'page.php?c=2&limit=5', function() {
$(this).find('#slider').nivoSlider();
});
});
For link:
<!-- updates links like so -->
<a class='nav' href='page.php?category=art&limit=5&c=1'>art</a>
// in the same document ready function
$('a.nav').click( function() {
var $link = $(this);
$('#content').load( $link.attr('href'), function() {
$(this).find('#slider').nivoSlider();
$link.addClass('selected'); // instead of setting bg directly to #828282;
});
return false; // to prevent normal link behavior
});
Would you not want to use $(document) rather than $(window)?
$(window).load(function() {
$('#slider').nivoSlider();
});
or shorthand
$(function() {
$('#slider').nivoSlider();
});

Categories

Resources