window.onload与<body onload =”” />


227

window.onload事件与标签onload事件之间到底有什么区别body?什么时候使用哪个以及如何正确完成?


2
您应该使用“
括住

Answers:


218

window.onload = myOnloadFunc并且<body onload="myOnloadFunc();">是使用同一事件的不同方法。使用起来window.onload不太麻烦-它使您的JavaScript脱离了HTML。

所有常见的JavaScript库,Prototype,ExtJS,Dojo,JQuery,YUI等,都为装入文档时发生的事件提供了很好的包装器。您可以侦听窗口的onLoad事件,并对此作出反应,但是在下载完所有资源之前不会触发onLoad,因此,只有在获取到最后一个大图像之后,事件处理程序才会执行。在某些情况下,这正是您想要的,在其他情况下,您可能会发现侦听DOM准备就绪的情况更为合适-此事件类似于onLoad,但会在不等待图像等下载的情况下触发。


57
但是,应该注意,两者之间存在差异。内联onload事件将myOnloadFunc()在全局上下文中调用(this将参考window)。通过javascript对其进行设置将使其在元素的上下文中执行(this指的是触发事件的元素)。在这种特殊情况下,它不会有任何变化,但与其他元素会有所不同。
mowwwalker

1
@Walkerneo:是的,绝对值得一提。当然,this如果需要,使用JS库可以覆盖引用的对象。
理查德·特纳

@RichardTurner您不需要使用库来更改上下文绑定。一个简单的.bind()调用即可完成
Kloar

这些天,您可以@Kloar,是的,但是您需要MSIE9 +。在较旧的MSIE(我回答时更为常见)上,您需要使用polyfill。
理查德·特纳

33

没什么区别,但是您都不应该使用两者。

在许多浏览器中,window.onload直到所有图像都加载后才触发该事件,这不是您想要的。基于标准的浏览器有一个名为的事件DOMContentLoaded,该事件会较早触发,但IE不支持(在编写此答案时)。我建议使用支持跨浏览器DOMContentLoaded功能的javascript库,或者找到可以使用的编写良好的函数。jQuery的$(document).ready()一个很好的例子。


53
未来的问题...如果没有jquery怎么办?
希德

54
从现在开始的问题。如果jQuery对于手头的项目来说过于刻板了怎么办?(不要敲jQuery,请自己使用。只是有时候只想从库中删除一个功能。)
Bradmage 2012年

14
当您说“不受IE支持”时,这是一个普遍的真理,还是仅对于特定版本的IE才是真实的?自从您编写此答案以来,浏览器世界发生了很多变化,也许是时候更新此答案了吗?
布莱恩·奥克利

8
IE9及更高版本现在支持DOMContentLoaded:developer.mozilla.org/en-US/docs/Web/Events/DOMContentLoaded
亚当(Adam)

6
:来自未来的报告,DOMContentLoaded现在所有主流浏览器都支持caniuse.com/#feat=domcontentloaded
何塞·戈麦斯

21

window.onload不用身体就能工作。仅使用脚本标签创建页面,然后在浏览器中将其打开。该页面不包含任何正文,但仍然可以使用。

<script>
  function testSp()
  {
    alert("hit");
  }
  window.onload=testSp;
</script>

6
如果您确实添加内容(应在body标签中),则没有body标签的HTML无效。另外,您的脚本标签缺少类型。永远不要依赖浏览器来修复不符合标准的代码!(因为浏览器在过去或将来可能会有所不同或完全不同。)
Kissaki 2011年

4
@Kissaki:标准HTML根本不需要body标签!
罗伯·西默

5
XHTML1指定<!ELEMENT html (head, body)>[1] -和HTML401指定<!ELEMENT HTML O O (%html.content;)<!ENTITY % html.content "HEAD, BODY">以及[2]。html51也指出A head element followed by a body element.html内容。[3] w3.org/TR/xhtml1/dtds.html#a_dtd_XHTML-1.0-Strict w3.org/TR/xhtml1/dtds.html#a_dtd_XHTML-1.0-Strict w3.org/TR/html51/semantics.html#the -html-element- 所以我想所有这些常用/正在使用的HTML标准需要一个body标签。:)
Kissaki

1
@Kissaki是XHTML,不是HTML。根据其SGML DTD,HTML允许省略开始和结束正文标签的标签,以及省略html和head标签的标签。w3.org/TR/html401/struct/global.html#edef-BODY Start tag: optional, End tag: optional
OdraEncoded

1
@Kissaki:html5不再需要脚本类型(如果是javascript),那么您就适合使用早期版本。
2015年

10

通常,我更喜欢使用<body onload="">事件。我认为将行为与内容尽可能分开是比较干净的。

就是说,在某些情况下(通常对我来说很少见),使用身体负荷可以稍微提高速度。

我喜欢使用Prototype,因此通常将类似的内容放在<head页面的>中:

document.observe("dom:loaded", function(){
  alert('The DOM is loaded!');
});

要么

Event.observe(window, 'load', function(){
  alert('Window onload');
});

以上是我在这里学到的技巧。我非常喜欢HTML之外的附加事件处理程序的概念。

(编辑以更正代码中的拼写错误。)


在什么情况下会更快,为什么?
Kissaki 2015年

对于所有“ I”(“我更喜欢”,“我认为”),此答案似乎都非常主观。如果进一步缺乏任何客观和可核查的事实,那将大大支持这种印象。
Kissaki 2015年

1
考虑到它是在6年前发布的,我会以一小撮盐来回答这个问题。非常欢迎您更新或发布您自己的改进答案。
Mark Biek

7

对一个客观问题有这么多主观的答案。“不引人注目的” JavaScript就像永远不使用gotos的旧规则一样是迷信。编写代码的方式可以帮助您可靠地实现目标,而不必遵循某人的新潮宗教信仰。

任何发现以下内容的人:

 <body onload="body_onload();">

过度分心过于自命不凡,没有优先考虑的事情。

我通常将我的JavaScript代码放在一个单独的.js文件中,但是我发现在HTML中挂接事件处理程序没有任何麻烦,顺便说一下,这是有效的HTML。


39
有充分的理由编写简洁的JavaScript。假设您有一个包含100个页面的Web应用程序,并且使用了<body onload =“ body_onload();”>方法,而不是将其放入每个页面包含的javascript文件中。然后想象一下由于某种原因您需要更改该函数的名称。将事件放入随附的javascript文件中,可以使更改变得更加简单,并且2)可以节省服务器资源,因为javascript文件可以缓存一年(在正确配置的服务器上),而不必一次又一次地下载相同的代码。
Andrew Ensley

21
因此,因为您不花时间学习为什么要推荐某些东西,所以将建议标记为“时髦的宗教信仰”?
hallvors 2012年

6
问题是“这两种方法之间有什么区别?”以及要求更好的建议。您的回答如何回答这个问题?
理查德·特纳2012年

1
在一个地方制作模块化解决方案并可以应用于大量文件的任何情况都比将代码添加到大量文件本身中的效果要好得多。对于原始构建时间,代码组织目的,可读性和将来的编辑而言,它更好。它不是新潮,实际上是Java和C ++等语言中存在的一个较旧的概念,Web程序员现在将其视为更好的编码方法。
Jimbo Jonny 2012年

1
在现代浏览器中,针对XSS攻击的一种很好的防御方法是使用内容安全策略禁用所有内联javascript。这是一个很好的理由,不要在HTML中使用onload属性。
格雷格·鲍尔

4

window.onload-在所有DOM,JS文件,图片,iframe,扩展名和其他文件完全加载后调用。等于$(window).load(function(){});

body onload=""-DOM加载后调用。等于$(document).ready(function(){});


1
有人能找到这个吗?我在许多论坛上都看到过此声明,但从未在规范中定义链接。
crempp 2014年

1
@crempp有body元素Global属性,所以我会说这是不正确的。但是您可以自己对此进行测试,请参阅jsbin.com/OmiViPAJ/1/edit。在那里,您可以看到在主体onload事件之前触发了图像onload事件。
Olaf Dietsche 2014年

2
这个答案与其他人矛盾。您可以提供来源吗?
Jimmy Breck-McKye 2014年

2
api.jquery.com/ready jQuery文档说:“ .ready()方法通常与<body onload =“”>属性不兼容。我认为在jQuery中,body.onload $(window).load(..)更接近,但我认为它们仍然有所不同。
ccsakuweb 2014年

2
这个答案是完全错误的,不应有任何赞成票。实际上,这种回答通常被认为是对readyvs onload事件的最大误解。load加载整个文档(包括所有脚本,图像和样式表)后触发。DOMContentLoadedDOM树已建成之后,但图像等,其之前的火灾DOMContentLoaded具有等效性document.ready,不load
rism

2

没有区别?

因此,原则上您可以同时使用两者(一次!!)

但是出于可读性和HTML代码的整洁度,我总是更喜欢window.onload!o]


1

如果您试图编写简洁的JS代码(应该这样做),则不应使用<body onload="">

据我了解,不同的浏览器对这两种浏览器的处理略有不同,但它们的运行方式却类似。在大多数浏览器中,如果您同时定义了两者,则将忽略它们。


1

将onload视为其他任何属性。例如,在输入框上,您可以输入:

<input id="test1" value="something"/>

或者您可以致电:

document.getElementById('test1').value = "somethingelse";

onload属性的工作方式相同,除了它使用函数作为其值而不是像value属性那样使用字符串。这也解释了为什么您可以“仅使用其中之一”的原因-调用window.onload为body标签重新分配onload属性的值。

而且,就像这里的其他人所说的那样,通常将样式和javascript与页面内容分开是比较干净的,这就是为什么大多数人建议使用window.onload或喜欢jQuery的ready函数的原因。


1

<body onload =“”>应该覆盖window.onload。

使用<body onload =“”>,document.body.onload可能为null,未定义或取决于浏览器的函数(尽管getAttribute(“ onload”)对于在字符串中获取匿名函数的主体应保持一致) 。使用window.onload,当您为其分配功能时,window.onload将是跨浏览器一致的功能。如果这对您很重要,请使用window.onload。

无论如何,window.onload更好地将JS与您的内容分离。当您可以使用window.onload时,没有太多理由使用<body onload =“”>。

在Opera中,window.onload和<body onload =“”>(甚至window.addEventListener(“ load”,func,false))的事件目标将是窗口,而不是Safari和Firefox中的文档。但是,“这”将是跨浏览器的窗口。

这就是说,重要的是,您应该包装杂物并使其保持一致,或使用为您提供帮助的库。


0

他们俩都一样。但是,请注意,如果两者都定义,则将仅调用其中之一。我通常避免直接使用它们中的任何一个。相反,您可以将事件处理程序附加到load事件。这样,您可以更轻松地合并其他JS程序包,这些程序包可能还需要将回调附加到onload事件。

任何JS框架都将具有用于事件处理程序的跨浏览器方法。


0

将内容,布局和行为分开是公认的标准。因此,<body onload="">尽管window.onload()可以完成相同的工作,但它们将更适合使用。


0

抱歉,在再次睡眠3年后再次实现该线程的轮回,但是也许我终于找到了window.onload=fn1;over 的无可争议的好处<body onload="fn1()">。它涉及到JS模块ES模块:当您的onload处理程序位于“经典” JS文件中(即,不带时<script type="module" … >,可以以任何一种方式引用;当您的onload处理程序位于“模块” JS文件中(即<script type="module" … >,以引用时,<body onload="fn1()">则以“ fn1”表示失败) ()未定义”错误。原因可能是在解析HTML之前未加载ES模块……但这只是我的猜测。无论如何,它window.onload=fn1;与模块完美配合...

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.