2012-05-27 3 views
5

Этот вопрос настолько прост, я уверен, что это должен быть дубликат что-то, хотя у меня есть looked for something similar.Javascript: Лучшее место для регистрации обработчиков событий

Мой вопрос в основном: Где лучше всего первоначально регистрировать обработчики событий для элементов HTML?

Самого простой способ зарегистрировать обработчик события, очевидно, просто сделать это рядным:

<div id = "mybutton" onclick = "doSomething()">Click me</div> 

Но это идет вразрез с подавляющим маршем к разделению логики и содержания в современной веб-разработке. Таким образом, в 2012 году вся логика/поведение должны выполняться в чистом коде Javascript. Это здорово, и это приводит к более удобному коду. Но вам все равно нужен начальный крючок, который соединяет ваши HTML-элементы с вашим кодом Javascript.

Обычно я просто делаю что-то вроде:

<body onload = "registerAllEventHandlers()"> 

Но ... это все-таки «обман», не правда ли - потому что мы все еще используем встроенный Javascript здесь. Но какие у нас есть другие варианты? Мы не можем сделать это в <script> тега в разделе <head>, потому что в тот момент мы не можем получить доступ к DOM, поскольку страница еще не загружена:

<head> 
<script type = "text/javascript"> 
    var myButton = document.getElementById("mybutton"); // myButton is null! 
</script> 
</head> 

ли мы размещаем <script> тег на внизу на странице что ли? Нравится:

<html> 
<body> 
... 
... 
<script type = "text/javascript"> 
    registerAllEventHandlers(); 
</script> 
</body> 
</html> 

Какая у вас лучшая практика?

ответ

2

Вы можете использовать window.onload:

<script type = "text/javascript"> 
    window.onload = registerAllEventHandlers; 
</script> 

Или, если вы используете :

$(registerAllEventHandlers); 

Использование onload работ, так как он регистрирует событие onload сразу, но срабатывает, когда DOM готова.

+0

-1: Событие 'window.onload' не эквивалентно использованию события' ready' jQuery: '' window.onload 'будет срабатывать, когда страница завершит загрузку, включая все внешние ресурсы (изображения, CSS и т. Д.), В то время как Событие jquery 'ready' запускается после завершения загрузки HTML, но перед внешними ресурсами. Использование 'window.onload' - плохая идея, потому что во многих случаях (многие изображения, медленное соединение и т. Д.) События JavaScript не будут регистрироваться в течение длительного времени. – georgebrock

+0

@slebetman: Можете ли вы рассказать о том, почему глупо присоединять обработчики событий JS до загрузки изображений (и т. Д.) И понимать различия между двумя разными методами? На сайте, предназначенном для обучения и обмена информацией, комментарий, говорящий «это глупо», не очень конструктивен. – georgebrock

0

У меня было a similar answer к этому, но был про JavaScript в целом. Но идея остается прежней - загружать скрипты перед закрытием тела.

Воспользуйтесь библиотеками, которые абстрагируют window.onload и событие готовности DOM. Таким образом, вы можете загрузить сценарии, как только DOM будет готов.

0

Вы должны зарегистрировать обработчики событий, как только DOM будет готов. Обнаружение этого во всех браузерах не всегда было простым, хотя с заметным исключением IE 8 (и ранее) наиболее широко используемые браузеры теперь поддерживают событие DOMContentLoaded (спасибо gengkev за то, что указали это в комментариях).

Это по существу эквивалентно вызову функции registerAllEventHandlers в конце вашего body, но это имеет то преимущество, что вам не нужно добавлять JavaScript в свой HTML.

Это значительно лучше, чем использование window.onload, поскольку оно не выполняется до тех пор, пока не будут загружены все ресурсы страницы (изображения, CSS и т. Д.).

Если вы используете одну из основных фреймворков JavaScript, вы можете очень легко обнаружить, когда DOM готов, даже в более старых версиях IE. не с JQuery вы бы использовать ready event:

jQuery(document).ready(function() { 
    // Your initialisation code here 
}); 

или стенографии:

jQuery(function() { … }); 

С Prototype вы бы использовать dom:loaded event:

document.observe("dom:loaded", function() { 
    // Your initialisation code here 
}); 
+1

DOMContentLoaded практически во всех браузерах, но IE <9 – gengkev

+0

Я не знал, что это так широко поддерживается сейчас, я думаю, что я так привык к тому, что jQuery мне помогает. Спасибо @gengkev – georgebrock

0

Лично у меня нет проблемы с добавлением onlclick="doSomething();" к элементу s. Никакой логики, просто вызов функции.

Вся логика там, где она должна быть: в функции, определенной в HEAD или отдельном файле.

Скажите, какая разница, когда вы добавляете href="somepage.html" или даже href="somepage.html#someanchor" в тег A.

+0

Я редко нахожу, что у меня есть только одна ссылка, которая нуждается в некотором поведении; часто это целая группа подобных ссылок. Когда это поведение изменяется или больше не требуется, мне гораздо удобнее изменять или удалять один файл .js, который определяет поведение и привязывает его к соответствующим ссылкам, вместо того, чтобы изменять или удалять многие атрибуты onclick многие ссылки. – georgebrock

+0

@georgebrock Вы можете сказать то же самое, если хотите переименовать/переструктурировать ваши HTML-файлы - вам все равно придется обращаться к каждому тегу 'A' и изменять атрибут' href'. Во всяком случае, в вашем случае нет необходимости изменять имя функции, просто перезапишите функцию. Если поведение onclick меняется, возможно, стоит изменить имя функции на что-то другое. Тем не менее, вы хорошо это понимаете. – Matthew

+0

Как только веб-сайт находится в общедоступной сети, изменение атрибутов 'href' в любом случае будет головной болью, потому что [классные URI не изменяются] (http://www.w3.org/Provider/Style/URI) (и когда они должны измениться, они должны 301 в новых местах). Но я отвлекся. Поскольку вы можете написать свой JavaScript так, чтобы существовала одна точка перемен и четкое разделение проблем, почему бы не сделать это? – georgebrock

Смежные вопросы