I am looking for a native JavaScript solution to jQuery's document.ready(). Looking at this thread, CMS suggested to just use the code that jQuery used to implement their document.ready(). I am looking at bindReady() but am unsure how I would incorporate that into my code. I currently have something such as:
$(document).ready( function() {
console.log('foo');
});
Basically when you need to do is replace the lines that have
jQuery.ready();
with the name of the function you want to call. If you want something that works like jQuery's ready registering method, build a function that makes a queue. Loop through the queue when the "ready" is triggered.
You asked for more info so here is a quick and dirty example not using a timeout. This is NOT production ready, just a basic POC.
(function () {
var ready = {
_readyQueue: [],
_hasRun: false,
_docReadyCalled : function() {
this._hasRun = true;
this._execute();
},
_execute: function () {
var func;
while (this._readyQueue.length) {
func = this._readyQueue.shift();
func();
}
},
register: function (func) {
this._readyQueue.push(func);
if (this._hasRun) {
this._execute();
}
}
}
window.docReady = ready.register.bind(ready); //use what ever global namespace you want here
function bindReady() {
/* This would be that jQuery code, I am just use window load here so not so much code */
//Not all browser support this, quick and dirty for example
window.addEventListener('load', ready._docReadyCalled.bind(ready), false);
}
bindReady();
})();
/* waiting for DOM to be ready */
docReady(function () { console.log("here"); });
docReady(function () { console.log("there"); });
/* Showing what happens when you call docReady after it is ready */
docReady(function () { console.log("registering ready again"); docReady(function () { console.log("I am here!"); }); });
Your best bet is to probably avoid using DOM events entirely. It gets really complicated when you want to load as early as possible but want to be certain it isn't too early. This is an easy and 100% reliable technique to execute code as soon as the DOM has completed loading:
<html>
<head>
<!-- head content, blah, blah, blah -->
<script>
var ready = function() {
// Put everything in this function that you want to run when the page loads
nowTheDomIsLoaded();
console.log('foo');
};
</script>
</head>
<body>
<!-- page content, blah, blah, blah -->
<script>ready();</script>
</body>
</html>
Basically you put everything you want run in a function (e.g. ready()) and the very last thing you do before the closing </body> tag is you execute that function. Because everything in the <body> has been parsed you know the DOM is loaded, and this doesn't take any special library.
Related
There are a number of posts on StackOverflow and other websites regarding the problem of avoiding namespace collisions. In my scenario, I just want a method in my JavaScript to be executed after the DOM is accessible.
If I do the following will it avoid namespace collisions?
<script type="text/javascript">window.onload = function() { //Define my namespace var here, and execute all my code }</script>
What if a script that is injected later also sets an onload function ? Will mine get overwritten? I'm fully aware that I can test this out, but I would also like some feedback as I am new to JavaScript and there could be a number of other scenarios which will do the something that I am not aware of.
EDIT: I need to support only Safari 5.0+
Yes, the last one will overwrite the previous ones.
The solution: use the new event API: addEventListener.
This is a fine Javascript way to do it right
function addLoadEvent(func) {
var oldonload = window.onload;
if (typeof window.onload != 'function') {
window.onload = func;
} else {
window.onload = function() {
if (oldonload) {
oldonload();
}
func();
}
}
}
addLoadEvent(nameOfSomeFunctionToRunOnPageLoad);
addLoadEvent(function() {
/* more code to run on page load */
});
Explained Source
There's lots of information on this, but here's the short version:
if you want to play nicely with onload, you can do
var prev_onLoad = window.onload;
window.onload = function() {
if (typeof(prev_onLoad)=='function')
prev_onLoad();
// rest of your onLoad handler goes here
}
and hope that other's play nicely or make sure that's the last setting of onload in the code.
However, more modern browsers have event registration functions (addEventListener and attachEvent on IE) which take care of this chaining among other things. Quite a few cross-browser onload event functions have been written which take care of this logic for you.
It'll be overriden .
In Javascript, when you define handle event like
window.onload = function(){
console.log("in Load function 1");
};
window.onload = function(){
console.log(" In load function 2");
};
That will make an " assign " window.onload => function() . And window.onload will be assign to last function .
But in jQuery,
You can handle event in many times and the browser will make all
$("body").on("click",function(){
console.log("make a callback function 1");
});
$("body").on("click",function(){
console.log("make a callback function 2");
});
Because jQuery make a callback not "assign".
Hope it helps you.
I have a problem with triggering a function which needs to be loaded only one time.But I don't want to put it into:
jQuery(document).ready(function ($) {
});
I want to run it separate.
I have tried:
jQuery(document).one(function () {
myfunction();
});
and some other stuff.
But couldn't solve it.
UPDATE:
I have my webservice on ready():
jQuery(document).ready(function ($) {
PageMethods.myWebSer(suc, fail);
});
function suc(){
//I want to run my function here , but only one time
//Examplle
//jQuery(document).one(function () {
// myfunction();
// });
}
Thank You
Just add another ready or load function : you may have as many as you want, they will all be called in order :
jQuery(document).ready(function() {
// this will be run
});
jQuery(document).ready(function() {
// and this one too (after the other one)
});
It you want it to run onload use:
jQuery(window).load(function () {
// run
});
Keep in mind that ready fires before load.
I'm binding an event like this, using prototype js:
$('country').observe('change',function(e) { ... });
How can I fire it once immediately?
in jQuery, I'd just tack on a .triggerHandler('change'). Is there something similar in prototype?
Use the load event. Something like this:
// calls addListeners when the document loads
Event.observe(window, 'load', addListeners, false);
function addListeners() {
// called onLoad
fireOnce();
// observer for the country dropdown
$('country').observe('change', function(event) {
fireOnChange();
});
}
function fireOnce() {
// do something
}
function fireOnChange() {
// do something
}
When the document loads, fireOnce() will execute. I use this technique all the time.
If using an extension is an option, I have had success in the past with event.simulate for this purpose.
It'll allow you to do something like:
$('country').simulate('change');
Try this:
var handler = function(e) {...};
$("country").observe("change",handler);
handler();
Alternatively (less readable, avoids temporary variable):
$("country").observe("change",(function(e) { ... return arguments.callee;})());
However, in both cases you will not be able to use this as you might expect. This solution is better suited to more general callbacks such as for setInterval
...if you know that it exists, and you know that you're not waiting for pageload or waiting for a script to load, why not just:
(function (el) {
if (!el) { return; }
doSomething(el);
}(document.getElementById("country")));
I'm getting alerted "hi" over and over again, how do I get it to do it once and stop:
function doSomething() {
alert('hi');
}
$(function() {
doSomething();
});
// Fired once when document is ready
$(document).one('ready', function () {
doSomething();
});
Using .one ensures this is done only once and not repeatedly.It is okay to put several document.ready event listeners (if you need other events to execute multiple times) as long as you do not overdo it, for the sake of readability.
.one is especially useful when you want the alert to appear the first time a web page is opened or when a mobile application is installed the first time.
I think you include your JS file multiple times from the HTML. Clean up your HTML.
Using:
$(function(){
});
is perfectly normal. Using more verbose form have no benefit. If you are writing a plugin, you might want to do this:
function($){
// $ always refers to jQuery here
...
}(jQuery);
// $ might not be defined here in compatibility mode.
Try with:
window.onload = function() {
doSomething();
}
Are you looking to do something like this?:
$(document).ready(function() {
doSomething();
});
The best way is ... with using cookie - like this:
$(document).ready(function () {
if ($.cookie("blocker") == 1) {
//your code or without code;
return;
} else {
//your code for first time
$.cookie("blocker", 1, {
expires: 1 / 24 / 60 //time, this is one minut
});
}
});
This code is good if you have smarty on your page
Raul is right, it would help to have the code...
But based on my experience with this, what you want is something more along the lines of:
var doSomething = function() {
alert('hi');
}
$(document).ready(function () {
doSomething();
});
You might want to stick to the more verbose style:
function doSomething() {
alert('hi');
}
$(document).ready(function() {
doSomething();
});
Not sure if I am being totally wrong here but I want to do something like this:
Have an external js page (on an external server)
Include the page - OK that is easy etc...
Have a Jquery function on the external page - well actually many functions
Call those functions directly onto the page.
All a bit like this:
External js page:
$(document).ready(function() {
function testit() {
$('#test').load('page.php');
}
function testit_1() {
$('#test_1').load('page_1.php');
}
function testit_1() {
$('#test_2').load('page_2.php');
}
});
Then on the actual page just call:
<script type="script/javascript">
testit();
</script>
<div id="test"></div>
Am I wrong or should that not work?
You dont need to define the functions within the ready function, but you have to call it within the ready function.
$(document).ready(function() {
testit();
});
function testit() {
$('#test').load('page.php');
}
function testit_1() {
$('#test_1').load('page_1.php');
}
function testit_2() {
$('#test_2').load('page_2.php');
}
Otherwise testit() will be called before the document is loaded. And at that moment the function doesn't even exist yet in your example.
Your functions are local to the scope of the anonymous function passed as the argument to $(document).ready(). Here's a simple example showing the behaviour you're seeing:
(function() {
function foo() {
alert("It shouldn't alert this...");
}
})();
foo();
To fix it, simply move your function declarations outside of the ready function:
function testit() {
$('#test').load('page.php');
}
function testit_1() {
$('#test_1').load('page_1.php');
}
function testit_2() {
$('#test_2').load('page_2.php');
}
And use the ready function (shorthand $(function() { ... })) in your main js file:
$(function() {
testit_1();
});
I'm not sure if I'm understanding you wrongly, but will you load an external page of an external server? This is not possible on normal browser security settings. You cannot perform a succesful XMLHttpRequest for a document that resides on a different server. Nearly all browsers will block this and leave you with nothing. You would have to write a server-side proxy that fetches the document and serves it back to the client.
That should work fine. Just be sure to include the external JS file in your page and execute testit() inside another $.ready() call:
<script type="script/javascript" src="http://someurl.com/external.js"></script>
<script type="script/javascript">
$.ready( function() {
testit();
} );
</script>
<div id="test"></div>
The location of a JS file is irrelevant. Once it is loaded into your page, it is executed in the context of that page.