0

采取以下代码:

HTML

<button id="button>click me</button>

JS - 版本 1

window.onload = init;

function init() {
    console.log('init called');
    var button = document.getElementById('button');
    button.onclick = buttonClickHandler;
}

function buttonClickHandler() {
    console.log('button clicked');
}

与相同的 HTML

JS - 版本 2

window.onload = init();

在这两种情况下,“init called”都会“立即”出现在控制台中,但在第二种情况下,它后面会出现一个错误,说明 button 为 null。

这里有两件事在起作用。1)在版本 1 中,它等待 DOM 加载 2)在版本 2 中,它发生在 DOM 加载之前,或者看起来如此。

我的问题。请尽可能清楚地解释版本 1 中发生了什么与版本 2 中发生了什么。什么是什么window.onload = init与什么window.onload = init()是什么的技术术语是什么?另请解释每个版本的行为。为什么 1 等待,而 2 没有?

脚本需要放在按钮元素之前,例如头部:http: //jsfiddle.net/XMEjr/1/

4

2 回答 2

9

版本 1 将init函数设置为在window.onload事件中调用的函数。该函数不在该行调用;它只是(作为一个值)分配给一个属性。

版本 2 将函数的结果设置为事件调用的结果。这是造成的差异。initwindow.onload()

显然在触发init之前调用函数onload(以获取该结果并将其设置为onload处理程序)。因此函数启动,无法通过buttonid 找到元素(因为 DOM 尚未准备好),因此getElementById返回 null。然后尝试访问onclick属性null停止它并出现错误。

于 2013-06-01T11:14:56.173 回答
0

在第二个中,您分配给 onload 调用 init 的结果 :)

如果您这样做,那将是等效的:

window.onload="init()"

在这种情况下,您正在分配一个在 DOM 准备就绪时进行评估的字符串。

如果你这样做

window.onload=init

您正在分配对函数的引用。再一次,当 DOM 准备好时,函数被调用

但如果你这样做:

 window.onload=init()

你可以做

function init() { alert ("this is called before onload, dom is not ready, button doesnt exist"); return init2; }

function init2() { alert ("this is called on load, dom is ready, button and everything in the body is now created"); }

希望你明白这一点。

顺便说一句,这种情况下做这样的事情会很有用:

window.onload=init()

function init() {
    if (IS_IPHONE) return init_iphone;
    if (IS_ANDROID) return init_android;
    if (IS_WINDOWS) return init_not_supported;
}

所以你选择哪个init方法来执行onload。

于 2013-06-01T11:19:30.440 回答