I'm using Simile to draw dynamic timelines. I am also using an in-house library to add a comment blog. Our in-house library uses the body element's onload event to initialize.
<body onload="initComments('myID')">
But Simile seems to have hijacked the onload for their own purpose so that initCo开发者_开发问答mments('myID')
never executes.
Short of changing the Simile code, how could I get my initializer to run?
I would prefer not to add another library (i.e. jQuery) just to solve the problem.
First off, as a general rule, you want to stay away from embedding JavaScript in your HTML as tag attributes.
Secondly, Simile is likely overwriting the onload
(using it the same way you are). So, you'll want to add your onload event after you've included Simile.
Using jQuery:
<script src="/js/blah/simile.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function() {
initComments('myID');
});
</script>
Using no library (found here):
<script src="/js/blah/simile.js" type="text/javascript"></script>
<script type="text/javascript">
function addOnloadEvent(fnc){
if ( window.addEventListener ) {
window.addEventListener( "load", fnc, false );
} else if ( window.attachEvent ) {
window.attachEvent( "onload", fnc );
}
else {
var oldOnload = window.onload || function() {};
window.onload = function(e) {
oldOnload(e);
window[fnc](e);
};
}
}
addOnloadEvent(function() { initComments('myID'); });
</script>
Use jQuery's $(document).ready
event, which lets you add an arbitrary number of handlers (unlike onload
).
Add in jQuery and use
$(document).ready(function(){
// Your code here...
});
There are a couple of other ways to write this in jQuery, but I find this is the most explanatory.
If you're doing any kind of JavaScript development, you need to be looking at jQuery. It's totally sweet!
Apart from the aforementioned jQuery solution (I however highly recommend to use it, it's great) here's the plain vanilla JS solution (as you didn't mention anything about jQuery in your question):
// Add this to top of your script.
window.onload = function () {
for (var i = 0; arguments.callee.functions.length > i; i++) {
arguments.callee.functions[i]();
}
};
window.onload.functions = [];
// Now for every onload function you want to add, do:
window.onload.functions.push(initComments('myID'));
By hijacked, you mean, Simile loads after your code and overwrites onload
? In that case, make sure you get behind it (as Justin says), and before you overwrite it yourself, store the value of onload
somewhere, so it still gets called (from your own handler).
That is, if you don't use jQuery.
If you look here you will see a solution that is what jQuery uses, I believe, or a modification of it, but it should work for your needs.
http://dean.edwards.name/weblog/2006/06/again/
// Dean Edwards/Matthias Miller/John Resig
function init() {
// quit if this function has already been called
if (arguments.callee.done) return;
// flag this function so we don't do the same thing twice
arguments.callee.done = true;
// kill the timer
if (_timer) clearInterval(_timer);
// do stuff
};
/* for Mozilla/Opera9 */
if (document.addEventListener) {
document.addEventListener("DOMContentLoaded", init, false);
}
/* for Internet Explorer */
/*@cc_on @*/
/*@if (@_win32)
document.write("<script id=__ie_onload defer src=javascript:void(0)><\/script>");
var script = document.getElementById("__ie_onload");
script.onreadystatechange = function() {
if (this.readyState == "complete") {
init(); // call the onload handler
}
};
/*@end @*/
/* for Safari */
if (/WebKit/i.test(navigator.userAgent)) { // sniff
var _timer = setInterval(function() {
if (/loaded|complete/.test(document.readyState)) {
init(); // call the onload handler
}
}, 10);
}
/* for other browsers */
/*window.onload = init; */
You will see that the last line is commented out. In the event it gets that far either you will clobber them (uncomment) or your code won't run, but this will work for the major browsers.
精彩评论