使用window.onload的最佳实践

时间:2009-02-17 23:12:35

标签: javascript joomla joomla1.5 onload

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

我的问题是:

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

7 个答案:

答案 0 :(得分:44)

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)事件,可以应用于文档对象,以了解何时可以操作文档(无需等待所有图像/样式表等加载)。

对于跨浏览器的支持,有很多“hacky”实现,因此我强烈建议使用此功能的框架。

答案 1 :(得分:10)

现代javascript框架引入了“文档就绪”事件的想法。当文档准备好对其执行DOM操作时,将触发此事件。只有在页面上的所有内容都加载后,“onload”事件才会触发。

除了“文档就绪”事件之外,框架还提供了一种方法来排队多个Javascript代码和函数,以便在事件触发时运行。

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

如果您不反对框架,那么您需要查看jQuery and document.readyPrototype and dom:loadedDojo and addOnLoad或Google以查找[您的框架]和“文档就绪”,

如果您没有选择框架但感兴趣,jQuery是一个很好的起点。它不会改变Javascript的任何核心功能,并且通常会让您不受约束,让您随心所欲地执行操作。

答案 2 :(得分:10)

在多个创建中覆盖window.onload事件。要附加功能,请使用 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);
}

答案 3 :(得分:2)

Joomla附带MooTools,因此您可以轻松地使用MooTools库获取其他代码。 MooTools附带一个名为domready的自定义事件,在加载页面并解析文档树时会触发该事件。

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

有关MooTools的更多信息,请访问here。 Joomla 1.5目前随MT1.1发布,而Joomla 1.6 alpha将包含MT1.2

答案 4 :(得分:1)

就个人而言,我更喜欢this method。它不仅允许你拥有多个onload函数,而且如果某个脚本在之前已经定义了它,那么这个方法足以处理它...唯一的问题left是指页面是否加载了几个不使用window.addLoad()函数的脚本;但那是他们的问题:)。

P.S。如果你想在以后“链接”更多功能,那也很棒。

答案 5 :(得分:1)

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

function load(){
   *code*
}

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

答案 6 :(得分:0)

由于我总是在文档底部包含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和bootstrap包含之前在页面上定义任何匿名加载器,并确保在jQuery出现时它将触发:

init.push(function() {

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

    $('[name="keyword_id"]').select2();
});