window.onload vs <body onload = “” />


227

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


2
вам слід використати "для оточення значення атрибута
Свен Ларсон

Відповіді:


218

window.onload = myOnloadFuncі <body onload="myOnloadFunc();">різні способи використання однієї і тієї ж події . Використання window.onloadменш нав'язливе - воно виводить ваш JavaScript з HTML.

Усі загальні бібліотеки JavaScript, Prototype, ExtJS, Dojo, JQuery, YUI тощо надають приємні обгортки навколо подій, які відбуваються під час завантаження документа. Ви можете слухати вікно події OnLoad та реагувати на це, але onLoad не запускається, поки не будуть завантажені всі ресурси, тому обробник подій не буде виконаний, поки не буде отримано останнє величезне зображення. В деяких випадках саме цього ви хочете, в інших ви можете виявити, що прослуховування, коли DOM готовий, є більш підходящим - ця подія схожа на OnLoad, але спрацьовує, не чекаючи завантаження зображень тощо.


57
Слід зазначити, що різниця є. Подія вбудованого завантаження буде викликати myOnloadFunc()в глобальному контексті ( thisбуде посилатися на window). Якщо встановити його через javascript, це змусить його виконувати в контексті елемента ( thisвідноситься до елемента, на якому подія була запущена). У цьому конкретному випадку це не зміниться, але з іншими елементами.
mowwwalker

1
@Walkerneo: Так, обов'язково варто зазначити. Звичайно, за допомогою бібліотеки JS можна змінити об'єкт, на який thisзвертається, якщо це потрібно.
Річард Тернер

@RichardTurner Вам не потрібно використовувати бібліотеку для зміни прив'язки контексту. Простий дзвінок .bind () робить це
Kloar

@Kloar ви можете сьогодні, так, але вам потрібен MSIE9 +. На старих MSIE, що було набагато частіше, коли я відповідав, вам знадобиться поліфіл.
Річард Тернер

33

Різниці немає, але і не слід використовувати жодне.

У багатьох браузерах window.onloadподія не спрацьовує, поки всі зображення не завантажуються, а це не те, що потрібно. Браузери на основі стандартів мають подію, DOMContentLoadedяка називається раніше, але IE не підтримується (на момент написання цієї відповіді). Я рекомендую використовувати бібліотеку javascript, яка підтримує функцію перехресного веб-переглядача DOMContentLoaded, або знайти добре написану функцію, яку ви можете використовувати. jQuery's $(document).ready()- хороший приклад.


53
Питання від майбутнього ... Що робити, якщо немає жодного запиту?
Сид

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 взагалі не потребує тегу тіла!
Роберт Сімер

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 та тегів заголовка відповідно до його SGML DTD. w3.org/TR/html401/struct/global.html#edef-BODY Start tag: optional, End tag: optional
OdraEncoded

1
@Kissaki: html5 більше не потребує типу сценарію (якщо це javascript), ви праві для більш ранніх версій.
Марк

10

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

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

Мені подобається використовувати прототип, тому я зазвичай вкладаю щось подібне до <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
Тож тому, що ви не переймаєтесь навчанням, чому щось рекомендується, ви позначите рекомендації "модними релігійними віруваннями"
зали засідань

6
Питання в тому, "в чому різниця між цими двома методами?", А також запит щодо рекомендації, щодо якої краще. Як ваша відповідь відповідає на це запитання?
Річард Тернер

1
Будь-яка ситуація, коли ви робите модульне рішення в 1 місці, яке можна застосувати до великої маси файлів, набагато краще, ніж додавання коду до кожної маси самих файлів. Краще для оригінального часу складання, організаційних цілей коду, для читабельності та для подальшого редагування. Це не модно, це насправді більш стара концепція, яка присутня у таких мовах, як java та c ++, які веб-програмісти зараз сприймають як далеко кращий спосіб кодування.
Jimbo Jonny

1
Однією з хороших захистів від XSS-атак у сучасних браузерах є відключення всіх вбудованих javascript за допомогою політики безпеки вмісту. Це досить вагомий привід не використовувати атрибут onload у вашому HTML.
Грег Бал Бал

4

window.onload- Викликається після того, як повністю завантажені файли DOM, JS, зображення, рамки, розширення та інші. Це дорівнює $ (window) .load (функція () {});

body onload=""- Викликається, коли DOM завантажений. Це дорівнює $ (document) .ready (function () {});


1
Хтось може це джерело? Я бачив це твердження на багатьох форумах, але ніколи не маючи посилання на те, де це визначено в специфікації.
Кремп

1
@crempp Є елемент тіла та атрибути Global , тому я б сказав, що це неправда. Але ви можете перевірити це самостійно, див. Jsbin.com/OmiViPAJ/1/edit . Там ви можете побачити подія зображення OnLoad обпалюють до того події тіла OnLoad.
Олаф Дієтше

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.
rism

2

Різниці немає ...

Тому в принципі ви можете використовувати обидва (по одному! -)

Але заради читабельності та чистоти html-коду я завжди віддаю перевагу window.onload! O]


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.


1

<body onload = ""> повинен замінити window.onload.

З <body onload = "">, document.body.onload може бути нульовим, невизначеним або функцією в залежності від браузера (хоча 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. Але "це" буде вікном у веб-переглядачах.

Це означає, що, коли це має значення, ви повинні загортати сиру та робити речі послідовними або використовувати бібліотеку, яка робить це за вас.


0

Вони обидва працюють однаково. Однак зауважте, що якщо обидва визначені, буде запрошено лише один із них. Я взагалі уникаю використання будь-якого з них безпосередньо. Натомість ви можете приєднати обробник події до події завантаження. Таким чином, ви можете легше включити інші пакети JS, які також можуть потребувати приєднання зворотного дзвінка до події завантаження.

Будь-яка програма JS матиме крос-браузерні методи для обробників подій.


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;відмінно працює з модулями ...

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.