С Prototype и подобными библиотеками вы не хотите подключать обработчики событий, назначая функции элементу onclick
и аналогичным свойствам; у этого стиля есть несколько недостатков (не менее важно то, что для элемента в событии может быть только один обработчик). Вместо этого используйте функцию observe
прототипа:
someElement.observe('click', functionRefHere);
// or
Element.observe(someElementOrID, 'click', functionRefHere);
Это также позволяет Prototype обходить некоторые ошибки IE, связанные с потерей памяти.
Вы можете посмотреть на событие прототипа dom:loaded
, которое происходит раньше, чем window.onload
(которое не произойдет, пока не загрузятся все ваши изображения и другие внешние ресурсы, что может быть секунда или две после страница отображается):
document.observe('dom:loaded', initFunctionRefHere);
Вы можете использовать делегирование события и просто смотреть свой элемент settings_nav, а не каждый дочерний узел в отдельности.
$(settings_nav).observe('click', handleNavClick);
function handleNavClick(event) {
var elm = event.findElement("some CSS selector here");
if (elm) {
event.stop();
// Handle it
}
}
Как видите, Event#findElement
принимает селектор CSS. Он начинается с фактического элемента, по которому щелкнули, и пытается сопоставить его с селектором; если это соответствует, это возвращает элемент, иначе это идет к родителю, чтобы видеть, соответствует ли это; и т. д. Таким образом, с вашим HTML вы можете искать li
(event.findElement('li')
) или ссылку (event.findElement('a')
).
Но если вы хотите наблюдать за каждым из них по отдельности, они могут использовать функцию (как в вашем примере):
$(settings_nav).childElements().invoke('observe', 'click', handleNavClick);
function handleNavClick(event) {
// Prototype makes `this` reference the element being observed, so
// `this` will be the `li` element in this example.
}
Независимо от того, смотрите ли вы каждый элемент отдельно или используете делегирование событий, зависит от того, что вы делаете (и от личных предпочтений). Всякий раз, когда что-то может изменить (например, добавляя и удаляя элементы навигации li
) или когда есть много вещей, которые нужно посмотреть, обращайтесь к делегированию событий - гораздо проще справиться с изменением наборов элементов, использующих делегирование событий и просто наблюдающих за родителем. При работе со стабильной структурой всего из нескольких вещей (как в вашем примере) может быть проще просто наблюдать за элементами по отдельности.
Оказавшись внутри вашего обработчика, вы можете использовать Element#down
, чтобы найти дочерние элементы (таким образом, из li
вы можете использовать li.down('div')
, чтобы найти div), или Element#next
, чтобы перейти к следующему элементу-брату (например, перейдя по ссылке на div). В любом случае, если у вас есть ссылка на div, вы можете использовать Element#show
и Element#hide
(или Element#toggle
).
Я рекомендую использовать именованные функции вместо анонимных (см. Мой пример выше). Именованные функции помогают вашим инструментам (отладчики, браузеры, показывающие ошибки и т. Д.). Только убедитесь, что не объявили именованную функцию и , используйте ее как выражение (например, не назначайте ее сразу чему-либо):
// Don't do this because of browser implementation bugs:
someElement.observe('click', function elementClickHandler(event) {
// ...
});
// Do this instead:
someElement.observe('click', elementClickHandler);
function elementClickHandler(event) {
// ...
}
... потому что, хотя вы должны быть в состоянии сделать это в соответствии со спецификацией, в действительности различные ошибки в различных браузерах делают его ненадежным ( article ).