开发者

Need to use body onload event, but third party JavaScript library has hijacked it

开发者 https://www.devze.com 2022-12-10 19:22 出处:网络
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.

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号