Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 25.07.2017, 22:56
Новичок на форуме
Отправить личное сообщение для GeekHacker Посмотреть профиль Найти все сообщения от GeekHacker
 
Регистрация: 25.07.2017
Сообщений: 9

Назначение обработчиков и SPA
Доброго времени.
Нужен совет от гуру.
Сразу скажу, что с web-разработкой знаком давно. Но что касается webА, то работал преимущественно с php. На js тоже успешно пишу, но не считаю его основным языком. Так что белых пятен хватает.
Задача следующая: требуется написать сайтик, но сайт должен представлять собой SPA. Никаких перезагрузок страниц, всё исключительно на ajaxЕ со всеми вытекающими и т.д.
Стоит отметить, что предполагается достаточно большое количество страниц. На каждой странице большое количество элементов взаимодействия с пользователем: ссылочки, кнопочки, формочки... Страницы, как правило, неоднотипные. Т.е. каждая страница, кроме пары блоков, не похожа на любую другую.
И тут меня начинают мучать сомнения. Как же наиболее эффективно организовать назначение обработчиков на события.
Рассматривается два варианта.
Первый.. Делегирование. На какой-то общий элемент (контейнер) навесить все обработчики.
Второй.. Навешивать обработчики через атрибуты элементов.
Всегда придерживался правила не смешивать html и js. С этой позиции делегирование представляется более правильным. Но не будет ли это слишком накладно в данном конкретном случае? Ведь когда внутри контейнера у нас произойдёт, скажем, клик, то у нас же запустятся все обработчики данного события на контейнере. А их будет много.
Вариант с атрибутами кажется менее накладным, но как-то и нравится меньше. Менее красиво что ли...
В общем, готов выслушать мнение сообщества.
Заранее благодарю.
Ответить с цитированием
  #2 (permalink)  
Старый 26.07.2017, 05:18
Профессор
Отправить личное сообщение для laimas Посмотреть профиль Найти все сообщения от laimas
 
Регистрация: 14.01.2015
Сообщений: 12,990

Сообщение от GeekHacker
Ведь когда внутри контейнера у нас произойдёт, скажем, клик, то у нас же запустятся все обработчики данного события на контейнере.
С чего вдруг? Два элемента А и В делегируют обработку щелчка родителю. Если щелкнули по В, то родителем будет обработан щелчок именно по нему, а не по А, так у него событие "автоматом" не возникнет. Кроме того можно использовать пространство имен.
Ответить с цитированием
  #3 (permalink)  
Старый 26.07.2017, 10:19
Новичок на форуме
Отправить личное сообщение для GeekHacker Посмотреть профиль Найти все сообщения от GeekHacker
 
Регистрация: 25.07.2017
Сообщений: 9

ну почему же? Есть два элемента с 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 всё разруливать, но это вообще не вариант. Т.к. логики будет много и там запутаться можно будет.
Ответить с цитированием
  #4 (permalink)  
Старый 26.07.2017, 10:32
Профессор
Отправить личное сообщение для laimas Посмотреть профиль Найти все сообщения от laimas
 
Регистрация: 14.01.2015
Сообщений: 12,990

Сообщение от GeekHacker
При клике на любой из элементов будут запускаться оба обработчика.
С чего вдруг, если событие одно, а делегирование, это определение источника события?
Ответить с цитированием
  #5 (permalink)  
Старый 26.07.2017, 11:14
Новичок на форуме
Отправить личное сообщение для GeekHacker Посмотреть профиль Найти все сообщения от GeekHacker
 
Регистрация: 25.07.2017
Сообщений: 9

Ну хотябы потому, что в данном случае мы вешаем на один элемент два обработчика события click. Разве нет? Запустите код из примера и посмотрите сами.
Ответить с цитированием
  #6 (permalink)  
Старый 26.07.2017, 11:18
Профессор
Отправить личное сообщение для laimas Посмотреть профиль Найти все сообщения от laimas
 
Регистрация: 14.01.2015
Сообщений: 12,990

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


Проверяйте, у каждого элемента будет свой обработчик, хотя делегируют они его одному родителю. При делегировании будет определяться источник события, в этом вся соль.
Ответить с цитированием
  #7 (permalink)  
Старый 26.07.2017, 13:17
Новичок на форуме
Отправить личное сообщение для GeekHacker Посмотреть профиль Найти все сообщения от GeekHacker
 
Регистрация: 25.07.2017
Сообщений: 9

А я разве утверждаю обратное?
Но если уж придираться к мелочам, то у дочерних элементов вообще нет обработчиков. Все обработчики мы вешаем на родителя. И срабатывают они на родителе. и при возникновении события сработает их столько, сколько мы их повесили на родителя.
А вся эта магия с делегированием работает исключительно благодаря тому, что события могут всплывать по структуре DOM. и что в объекте события нам доступен реальный источник события. Разница между target и currentTarget.
event.target - элемент на котором произошло событие и от которого оно начало всплытие.
event.currentTarget - элемент, на котором сработал обработчик события.
Я специально не стал использовать в примере какие-либо библиотеки типа JQuery, т.к. получается менее наглядно.
Берите мой пример и при помощи контрольной переменной смотрите сколько было срабатываний обработчиков при клике на любом из дочерних элементов.
Ответить с цитированием
  #8 (permalink)  
Старый 26.07.2017, 13:34
Профессор
Отправить личное сообщение для laimas Посмотреть профиль Найти все сообщения от laimas
 
Регистрация: 14.01.2015
Сообщений: 12,990

Сообщение от GeekHacker
И срабатывают они на родителе. и при возникновении события сработает их столько, сколько мы их повесили на родителя.
С чего вдруг при щелчке на одном элементе, возникнут щелчки на всех других дочерних?

В голове что-то не укладывается. Хрен с ним, пусть будет так:

$a = [
    'a' => function() {},
    'b' => function() {}    
]


Если $a['b'](), то означает ли, что при этом будет выполнено и $a['a']()? А почему при щелчке по Span должен выполняться и обработчик А?

О чем речь?
Ответить с цитированием
  #9 (permalink)  
Старый 26.07.2017, 13:48
Профессор
Отправить личное сообщение для laimas Посмотреть профиль Найти все сообщения от laimas
 
Регистрация: 14.01.2015
Сообщений: 12,990

GeekHacker,
доперло что не нравится - цена метода?
Ответить с цитированием
  #10 (permalink)  
Старый 26.07.2017, 14:25
Новичок на форуме
Отправить личное сообщение для GeekHacker Посмотреть профиль Найти все сообщения от GeekHacker
 
Регистрация: 25.07.2017
Сообщений: 9

А причём тут дочерние?
Речь о том, что событие возникает на родителе. С этим вы же спорить не будете? Всплытие ведь. А на родителе у нас висит два обработчика. Вот они и срабатывают.
Ещё раз, берите мой пример и смотрите как работают обработчики. Какое сообщение мы получим в алерте и каким станет значение x после клика на любом потомке.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Выбор фреймворка для крупного SPA приложения. AgRuN Библиотеки/Тулкиты/Фреймворки 1 25.03.2017 15:56
ie8 и назначение обработчиков циклом innowed Events/DOM/Window 4 14.03.2017 09:42
Front-end разработчик ищет заказы/работу, SPA приветствуются rekzi Работа 0 07.06.2016 23:42
ajax форум, spa torsar AJAX и COMET 0 21.10.2015 20:52
Назначение обработчиков Через свойство объекта igor' Общие вопросы Javascript 3 05.09.2010 20:07