window.onload против <body onload = “” />

227

В чем конкретно разница между window.onloadсобытием и onloadсобытием bodyтега? Когда я использую, что и как должно быть сделано правильно?

Manu
источник
2
Вы должны использовать ", чтобы окружить значение атрибута
Свен Ларсон

Ответы:

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: Да, определенно стоит отметить. Конечно, используя библиотеку JS, можно thisпри желании переопределить объект, на который ссылается.
Ричард Тернер
@RichardTurner Вам не нужно использовать библиотеку для изменения привязки контекста. Это делает простой вызов .bind ()
Kloar
@ Клоар, ты можешь в эти дни, да, но тебе нужен MSIE9 +. На старом MSIE, который был гораздо более распространенным, когда я отвечал, вам понадобится полифилл.
Ричард Тернер
33

Там нет никакой разницы, но вы также не должны использовать.

Во многих браузерах window.onloadсобытие не запускается до тех пор, пока не будут загружены все изображения, а это не то, что вам нужно. В основанных на стандартах браузерах есть событие, DOMContentLoadedкоторое вызывается раньше, но не поддерживается IE (на момент написания этого ответа). Я бы рекомендовал использовать библиотеку javascript, которая поддерживает кросс-браузерную функцию DOMContentLoaded, или найти хорошо написанную функцию, которую вы можете использовать. JQuery $(document).ready(), хороший пример.

jcampbell1
источник
53
Вопрос из будущего ... Что делать, если нет jquery?
Сид
54
Вопрос из настоящего. Что делать, если jQuery является избыточным для данного проекта? (Не стучите в jQuery, используйте его самостоятельно. Просто иногда требуется только одна функция из библиотеки ...)
Bradmage
14
Когда вы говорите «не поддерживается IE», это универсальная правда или только правда для определенных версий IE? Так как в мире браузеров многое изменилось с тех пор, как вы написали этот ответ, может быть, пришло время обновить этот ответ?
Брайан Оукли
8
DOMContentLoaded теперь поддерживается в IE9 и выше: developer.mozilla.org/en-US/docs/Web/Events/DOMContentLoaded
Адам
6
Отчеты о будущем DOMContentLoaded теперь поддерживаются всеми основными браузерами: caniuse.com/#feat=domcontentloaded
Хосе Гомес,
21

window.onloadможет работать без тела. Создайте страницу только с тегами скрипта и откройте ее в браузере. Страница не содержит никакого тела, но все еще работает ..

<script>
  function testSp()
  {
    alert("hit");
  }
  window.onload=testSp;
</script>
Джон Джозеф
источник
6
HTML без тега body недействителен, если вы действительно добавляете контент (который должен быть в теге body). Также в вашем теге скрипта отсутствует тип. Никогда не полагайтесь на браузеры, исправляющие ваш нестандартный код! (Поскольку браузеры могут делать это по-другому или вообще не делать этого в прошлом или будущем.)
Kissaki
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-элемент - Так что я предполагаю , что все эти стандарты HTML общих / в использовании делает требует тега тела. :)
Киссаки
1
@ Kissaki это XHTML, а не HTML. HTML допускает пропуск тегов как начального, так и конечного тегов тела, а также пропуск тегов html и head согласно его DTD SGML. w3.org/TR/html401/struct/global.html#edef-BODY Start tag: optional, End tag: optional
OdraEncoded
1
@ Kissaki: html5 больше не нуждается в типе скрипта (если это javascript), вы подходите для более ранних версий.
Марк
10

Обычно я предпочитаю не использовать <body onload=""событие>. Я думаю, что чище держать поведение как можно более отделенным от контента.

Тем не менее, есть случаи (обычно довольно редкие для меня), когда использование нагрузки на тело может дать небольшой прирост скорости.

Мне нравится использовать Prototype, поэтому я обычно помещаю что-то вроде этого на <head> моей странице:

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

или

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

Выше приведены трюки, которые я узнал здесь . Мне очень нравится концепция обработчиков событий присоединения вне HTML.

(Изменить, чтобы исправить орфографическую ошибку в коде.)

Марк Бик
источник
В каких случаях это будет быстрее и почему?
Киссаки
Этот ответ кажется очень субъективным со всеми «я» («я предпочитаю», «я думаю»). Это, если в дальнейшем отсутствуют какие-либо объективные и проверяемые факты, в значительной степени поддерживает это впечатление.
Киссаки
1
Я бы взял этот ответ с крошкой соли, учитывая, что он был опубликован более 6 лет назад. Вы можете обновить его или опубликовать свой собственный улучшенный ответ.
Марк Биек
7

так много субъективных ответов на объективный вопрос. «Ненавязчивый» JavaScript - это суеверие, как и старое правило никогда не использовать gotos. Напишите код таким образом, который поможет вам надежно достичь своей цели, а не в соответствии с чьими-то модными религиозными убеждениями.

Тот, кто находит:

 <body onload="body_onload();">

чрезмерно отвлекать слишком претенциозно и у них нет четких приоритетов.

Я обычно помещаю свой код JavaScript в отдельный файл .js, но я не нахожу ничего сложного в подключении обработчиков событий в HTML, который, кстати, является допустимым HTML.


источник
39
Есть веская причина для написания ненавязчивого JavaScript. Скажем, у вас есть веб-приложение на 100 страниц, и вы использовали метод <body onload = "body_onload ();"> вместо того, чтобы помещать его в файл javascript, включенный в каждую страницу. Затем представьте, что вам необходимо изменить имя этой функции по какой-то причине. Помещение события во включенный файл javascript 1) значительно упрощает изменения и 2) экономит ресурсы сервера, поскольку файлы javascript могут кэшироваться в течение года (на правильно настроенном сервере) вместо загрузки одного и того же кода снова и снова.
Эндрю Энсли
21
Итак, потому что вы не беспокоитесь о том, почему что-то рекомендуется, вы называете рекомендации «модными религиозными убеждениями» ??
Hallvors
6
Вопрос «в чем разница между этими двумя методами?» Вместе с запросом рекомендации, для которой лучше. Как ваш ответ отвечает на этот вопрос?
Ричард Тернер
1
Любая ситуация, когда вы делаете модульное решение в одном месте, которое может быть применено к большой массе файлов, намного лучше, чем добавление кода к каждой массе файлов. Это лучше для оригинального времени сборки, организационных целей кода, для удобочитаемости и для будущего редактирования. Это не модно, на самом деле это более старая концепция, присутствующая в таких языках, как java и c ++, которые веб-программисты теперь используют как гораздо лучший способ написания кода.
Джимбо Джонни
1
Хорошей защитой от XSS-атак в современных браузерах является отключение всего встроенного JavaScript с помощью вашей Политики безопасности контента. Это довольно веская причина не использовать атрибут onload в своем HTML.
Грег Болл
4

window.onload- Вызывается после полной загрузки всех файлов DOM, JS, изображений, фреймов, расширений и других. Это равно $ (window) .load (function () {});

body onload=""- Вызывается после загрузки DOM. Это равно $ (document) .ready (function () {});

Есу радж
источник
1
Может ли кто-нибудь найти это? Я видел это утверждение на многих форумах, но никогда со ссылкой на то, где оно определено в спецификации.
crempp
1
@crempp Существует элемент body и глобальные атрибуты , поэтому я бы сказал, что это не так. Но вы можете проверить это сами, см. Jsbin.com/OmiViPAJ/1/edit . Там вы можете видеть, что событие загрузки изображения запускается до события загрузки тела.
Олаф Дитче
2
Этот ответ противоречит другим; Можете ли вы предоставить источник?
Джимми Брек-МакКей
2
api.jquery.com/ready Документация jQuery гласит: «Метод .ready () обычно несовместим с атрибутом <body onload =" ">». Я думаю, что в jQuery ближе к body.onload $ (window) .load (..), но я думаю, что они все еще разные.
ccsakuweb
2
Этот ответ совершенно неправильный и не должен иметь никаких голосов. На самом деле этот тип ответа , как правило , цитируются как среди самых больших заблуждений о readyпротив onloadсобытий. loadсрабатывает после загрузки всего документа, включая все скрипты, изображения и таблицы стилей. DOMContentLoadedсрабатывает после того, как дерево DOM было построено, но до изображений и т. д. Это DOMContentLoadedэквивалентно document.ready, а не load.
Ризм
2

Там нет разницы ...

Так что принципиально вы можете использовать оба (по одному! -)

Но для удобства чтения и чистоты HTML-кода я всегда предпочитаю window.onload! O]

roenving
источник
1

Если вы пытаетесь написать ненавязчивый код JS (и вы должны это делать), то вам не следует его использовать <body onload="">.

Насколько я понимаю, разные браузеры работают по-разному, но работают одинаково. В большинстве браузеров, если вы определите оба, один из них будет проигнорирован.

Доктор боб
источник
1

Думайте о нагрузке как о любом другом атрибуте. Например, в поле ввода вы можете поместить:

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

Или вы можете позвонить:

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

Атрибут onload работает так же, за исключением того, что он принимает функцию в качестве значения вместо строки, как атрибут value. Это также объясняет, почему вы можете «использовать только один из них» - вызов window.onload переназначает значение атрибута onload для тега body.

Кроме того, как и другие здесь говорят, обычно лучше держать стиль и javascript отдельно от содержимого страницы, поэтому большинство людей советуют использовать window.onload или как готовую функцию jQuery.

Soldarnal
источник
1

<body onload = ""> должен переопределить window.onload.

При <body onload = ""> document.body.onload может иметь значение null, undefined или функцию в зависимости от браузера (хотя getAttribute ("onload") должен быть несколько согласованным для получения тела анонимной функции в виде строки) , С помощью window.onload, когда вы назначаете ему функцию, window.onload будет функцией в разных браузерах. Если это важно для вас, используйте window.onload.

window.onload лучше в любом случае лучше отделить JS от вашего контента. Нет особой причины использовать <body onload = ""> в любом случае, когда вы можете использовать window.onload.

В Opera целью событий для window.onload и <body onload = ""> (и даже window.addEventListener ("load", func, false)) будет окно вместо документа, как в Safari и Firefox. Но «это» будет окном через браузеры.

Это означает, что, когда это имеет значение, вы должны обернуть руду и привести все в соответствие или использовать библиотеку, которая сделает это за вас.

Shadow2531
источник
0

Они оба работают одинаково. Тем не менее, обратите внимание, что если оба определены, будет вызван только один из них. Я вообще избегаю использовать любой из них напрямую. Вместо этого вы можете прикрепить обработчик события к событию загрузки. Таким образом, вы можете легче включать другие пакеты JS, которые также могут присоединять обратный вызов к событию onload.

Любая среда JS будет иметь кросс-браузерные методы для обработчиков событий.

KernelM
источник
0

Это общепринятый стандарт для разделения контента, макета и поведения. Таким образом, window.onload () будет более подходящим для использования, <body onload="">хотя оба будут выполнять одну и ту же работу.

Раджешваран С.П.
источник
0

Извините за реинкарнацию этой темы снова после еще 3 лет сна, но, возможно, я наконец-то нашел бесспорную выгоду window.onload=fn1;более <body onload="fn1()">. Это относится к модулям JS или модулям ES : когда ваш onloadобработчик находится в «классическом» файле JS (т. Е. Ссылается без него <script type="module" … >, возможен любой из этих способов; когда ваш onloadобработчик находится в файле JS «модуля» (т. Е. Упоминается <script type="module" … >, <body onload="fn1()">произойдет сбой с помощью «fn1 () не определено "ошибка. Возможно, причина в том, что модули ES не загружаются до синтаксического анализа HTML ... но это только мое предположение. Во всяком случае, window.onload=fn1;прекрасно работает с модулями ...

Петр Пивонка
источник