Назначение обработчиков и SPA
Доброго времени.
Нужен совет от гуру. Сразу скажу, что с web-разработкой знаком давно. Но что касается webА, то работал преимущественно с php. На js тоже успешно пишу, но не считаю его основным языком. Так что белых пятен хватает. Задача следующая: требуется написать сайтик, но сайт должен представлять собой SPA. Никаких перезагрузок страниц, всё исключительно на ajaxЕ со всеми вытекающими и т.д. Стоит отметить, что предполагается достаточно большое количество страниц. На каждой странице большое количество элементов взаимодействия с пользователем: ссылочки, кнопочки, формочки... Страницы, как правило, неоднотипные. Т.е. каждая страница, кроме пары блоков, не похожа на любую другую. И тут меня начинают мучать сомнения. Как же наиболее эффективно организовать назначение обработчиков на события. Рассматривается два варианта. Первый.. Делегирование. На какой-то общий элемент (контейнер) навесить все обработчики. Второй.. Навешивать обработчики через атрибуты элементов. Всегда придерживался правила не смешивать html и js. С этой позиции делегирование представляется более правильным. Но не будет ли это слишком накладно в данном конкретном случае? Ведь когда внутри контейнера у нас произойдёт, скажем, клик, то у нас же запустятся все обработчики данного события на контейнере. А их будет много. Вариант с атрибутами кажется менее накладным, но как-то и нравится меньше. Менее красиво что ли... В общем, готов выслушать мнение сообщества. Заранее благодарю. |
Цитата:
|
ну почему же? Есть два элемента с id a и с id b внутри родителя с id d.
Мы хотим обрабатывать клики на a и b через делегирование. Для чего вешаем два обработчика на d. При клике на любой из элементов будут запускаться оба обработчика. Другое дело, что внутри обработчиков мы вычисляем event.target и полезный код будет выполнен только в случае, если event.target тот, что нам нужен, но это не отменяет того факта, что запустятся оба обработчика. Топорный пример var x = 2; document.addEventListener('DOMContentLoaded', function(){ //первый обработчик document.getElementById('d').addEventListener('click', function(event){ x++; var target = event.target; while(target != this){ if(target.id == 'a'){ alert('Вы кликнули по элементу с ID "a"'); return; } else target = target.parentNode; } }); //второй обработчик document.getElementById('d').addEventListener('click', function(event){ x++; var target = event.target; while(target != this){ if(target.id == 'b'){ alert('Вы кликнули по элементу с ID "b"'); return; } else target = target.parentNode; } }); }); По клику на любом элементе мы увидим сообщение (одно), т.к. определив event.target мы всё правильно разрулили, но значением переменной x будет 2. Т.к. оба обработчика инкрементировали предыдущее её значение. Да, можно было бы повесить один обработчик и в условиях зависимо от event.target всё разруливать, но это вообще не вариант. Т.к. логики будет много и там запутаться можно будет. |
Цитата:
|
Ну хотябы потому, что в данном случае мы вешаем на один элемент два обработчика события click. Разве нет? Запустите код из примера и посмотрите сами.
|
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <style> </style> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script> <script> $(function() { $('div').on('click', 'a', function(e) { alert(e.target.tagName) }); $('div').on('click', 'span', function(e) { alert(e.target.tagName) }); }); </script> </head> <body> <div> <a>A</a> <span>Span</span> </div> </body> </html> Проверяйте, у каждого элемента будет свой обработчик, хотя делегируют они его одному родителю. При делегировании будет определяться источник события, в этом вся соль. |
А я разве утверждаю обратное?
Но если уж придираться к мелочам, то у дочерних элементов вообще нет обработчиков. Все обработчики мы вешаем на родителя. И срабатывают они на родителе. и при возникновении события сработает их столько, сколько мы их повесили на родителя. А вся эта магия с делегированием работает исключительно благодаря тому, что события могут всплывать по структуре DOM. и что в объекте события нам доступен реальный источник события. Разница между target и currentTarget. event.target - элемент на котором произошло событие и от которого оно начало всплытие. event.currentTarget - элемент, на котором сработал обработчик события. Я специально не стал использовать в примере какие-либо библиотеки типа JQuery, т.к. получается менее наглядно. Берите мой пример и при помощи контрольной переменной смотрите сколько было срабатываний обработчиков при клике на любом из дочерних элементов. |
Цитата:
В голове что-то не укладывается. Хрен с ним, пусть будет так: $a = [ 'a' => function() {}, 'b' => function() {} ] Если $a['b'](), то означает ли, что при этом будет выполнено и $a['a']()? А почему при щелчке по Span должен выполняться и обработчик А? О чем речь? |
GeekHacker,
А что вы предлагаете? Да, нет нативного метода для того что вы хотите. Вы можете использовать либо кастомный метод либо ждать когда появится нативный. |
GeekHacker,
доперло что не нравится - цена метода? |
Часовой пояс GMT +3, время: 14:28. |