使用window.onload的最佳做法

我开发Joomla网站/组件/模块和插件,每隔一段时间,我都需要使用能够在页面加载时触发事件的JavaScript。 大多数情况下,这是使用window.onload函数完成的。

我的问题是:

  1. 这是在页面加载上触发JavaScript事件的最好方法,还是有更好/更新的方法?
  2. 如果这是触发页面加载事件的唯一方法,确保多个事件可以通过不同脚本运行的最佳方法是什么?

window.onload = function(){}; 工作,但正如你可能已经注意到的, 它允许你指定只有一个监听器

我会说这样做的更好/更新的方法是使用框架,或者只是使用简单的本地addEventListenerattachEvent (对于IE)方法的实现,它允许您删除事件的侦听器好。

这是一个跨浏览器的实现:

 // Cross-browser implementation of element.addEventListener() function listen(evnt, elem, func) { if (elem.addEventListener) // W3C DOM elem.addEventListener(evnt,func,false); else if (elem.attachEvent) { // IE DOM var r = elem.attachEvent("on"+evnt, func); return r; } else window.alert('I\'m sorry Dave, I\'m afraid I can\'t do that.'); } // Use: listen("event name", elem, func); 

对于window.onload的情况使用: listen("load", window, function() { });


编辑我想通过添加其他人指出的宝贵信息来扩展我的答案。

这是关于DOMContentLoaded (Mozilla,Opera和webkit nightlies目前支持这一点)和onreadystatechange (对于IE) 事件 ,它们可以应用于文档对象,以了解何时可以操作文档(无需等待所有的图像/样式表等)被加载)。

对于跨浏览器的支持,有很多“黑客”实现,所以我强烈build议使用这个特性的框架。

现代的JavaScript框架已经引入了“文档就绪”事件的概念。 这是一个当文档准备好对其进行DOM操作时将触发的事件。 “onload”事件只有在页面上的所有事件加载后才会触发。

随着“文档就绪”事件,框架提供了一种方法来排队多个位的JavaScript代码和function,以便在事件触发时运行。

所以,如果你反对框架,最好的办法是实现你自己的document.onload队列。

如果您不反对框架,那么您将需要查看jQuery和document.ready , Prototype和dom:加载 , Dojo和addOnLoad或Google for [框架]和“文档准备”。

如果你还没有select框架,但有兴趣,jQuery是一个很好的开始。 它不会改变任何Javascript的核心function,并且通常会保持你的方式,让你随心所欲地做你想做的事情。

window.onload事件在多个创build中被覆盖。 要追加函数,请使用window.addEventListener(W3C标准)或window.attachEvent(对于IE)。 使用下面的代码工作。

 if (window.addEventListener) // W3C standard { window.addEventListener('load', myFunction, false); // NB **not** 'onload' } else if (window.attachEvent) // Microsoft { window.attachEvent('onload', myFunction); } 

Joomla附带MooTools,所以你会发现使用MooTools库更容易获得额外的代码。 MooTools附带了一个名为domready的自定义事件,当页面被加载并且文档树被parsing时会触发。

 window.addEvent( domready, function() { code to execute on load here } ); 

有关MooTools的更多信息可以在这里find。 目前Joomla 1.5与MT1.1一起发布,而Joomla 1.6 alpha将包含MT1.2

就我个人而言,我更喜欢这种方法 。 它不仅允许你有多个onload函数,但是如果有一些脚本你find它之前已经定义了它,这个方法已经足够好处理了…剩下的唯一问题就是如果一个页面加载了几个脚本使用window.addLoad()函数; 但那是他们的问题:)。

PS如果你想在后面“链接”更多的function,这也很好。

这是肮脏但更短的方式:P

 function load(){ *code* } window[ addEventListener ? 'addEventListener' : 'attachEvent' ] ( addEventListener ? 'load' : 'onload', function(){} ) 

由于我总是在文档的底部包含jQuery / bootstrap JS文件,并且没有对文档的访问权限,所以我开发了一个小小的“init”插件,它是我的页面顶部包含的唯一一个JS脚本:

 window.init = new function() { var list = []; this.push = function(callback) { if (typeof window.jQuery !== "undefined") { callback(); } else { list.push(callback); } }; this.run = function() { if (typeof window.jQuery !== "undefined") { for(var i in list) { try { list[i](); } catch (ex) { console.error(ex); } } list = []; } }; if (window.addEventListener) { window.addEventListener("load", this.run, false); } else if (window.attachEvent) { window.attachEvent("onload", this.run); } else { if (window.onload && window.onload !== this.run) { this.push(window.onload); } window.onload = this.run; } }; 

使用这个,我可以在页面上定义任何匿名加载器,在jQuery和引导包含之前,确保一旦存在jQuery就会触发它:

 init.push(function() { $('[name="date"]').datepicker({ endDate: '0d', format: 'yyyy-mm-dd', autoclose: true }).on('hide', function() { // $.ajax }); $('[name="keyword_id"]').select2(); });