Недавно в канале Измерение слабости возник вопрос, который мы слышим слишком часто. Перефразируя, получилось примерно так:

Я установил правило в Adobe DTM, которое должно срабатывать, когда пользователь нажимает на определенную ячейку таблицы, но DTM никогда не обнаруживает щелчок. Есть идеи, как заставить DTM обнаруживать щелчок? Я заметил, что у нашего приложения есть собственный прослушиватель кликов в ячейке таблицы, а внутри обработчика у нас есть event.stopPropagation().

По опыту этого пользователя, иногда DTM трудно определить, когда произошло событие. Давайте посмотрим, почему это происходит в DTM и как обнаружение событий в Adobe Experience Platform Launch более надежно и прозрачно решает проблему этого пользователя.

В JavaScript и объектной модели документа (DOM) события обрабатываются очень упорядоченно посредством процесса, называемого захватом и восходящей цепью событий. Чтобы понять, как работает этот процесс, давайте рассмотрим простой пример, в котором у нас есть HTML документ, который содержит тело, которое содержит единственную таблицу, который содержит единственное тело таблицы (tbody), которое содержит единственную строку таблицы (tr), содержащую единственную ячейку таблицы (td) . Иерархия выглядит так:

Разработчики программного обеспечения могут написать JavaScript, который добавляет один или несколько прослушивателей событий щелчка к любому из элементов, определенных в нашей иерархии. Какими бы ни были причины, приложение может зарегистрировать прослушиватель событий щелчка в теле, два прослушивателя событий щелчка в таблице и прослушиватель событий щелчка в ячейке таблицы или какой-либо другой вариант в зависимости от того, что приложение пытается сделать.

Когда к элементу добавляется прослушиватель событий, он добавляется либо для «фазы захвата», либо для «фазы восходящей цепочки». Это очень важно понимать. Мы еще не обсуждали, что это за фазы, но мы сделаем это в два встряхивания ягненка за хвост.

Теперь предположим, что пользователь нажимает на ячейку таблицы. Событие обрабатывается в три этапа в следующем порядке:

  1. Фаза захвата: на этой фазе выполняются все слушатели, зарегистрированные для фазы захвата в документе, затем все слушатели, зарегистрированные для фазы захвата в теле , затем все слушатели зарегистрировались для фазы захвата в таблице, затем все слушатели зарегистрировались для фазы захвата в теле таблицы, а затем все слушатели зарегистрировались для захвата фазу в строке таблицы.
  2. Целевая фаза: на этой фазе выполняются все прослушиватели, зарегистрированные в ячейке таблицы, независимо от того, были ли они зарегистрированы для фазы захвата или фазы восходящей цепочки.
  3. Фаза всплытия: на этом этапе выполняются все слушатели, зарегистрированные для фазы восходящей цепочки в строке таблицы, а затем все слушатели, зарегистрированные для фазы восходящей цепочки в теле таблицы. , затем все слушатели зарегистрировались для фазы восходящей цепочки в таблице, затем все слушатели зарегистрировались для фазы восходящей цепочки в теле, а затем все слушатели зарегистрировались для фаза всплытия в документе.

Картина говорит тысячу слов, поэтому они говорят:

Ограничения в DTM

Вот кикер. Выше мы описали то, как это обычно работает в «современных браузерах». Примечательно, что Internet Explorer 8 и более ранние версии не поддерживают фазу захвата, а DTM был разработан для работы с Internet Explorer 8 (и даже более ранними браузерами до того, как их поддержка впоследствии была прекращена). Из-за этого вот с чем пришлось работать DTM:

Для обнаружения событий щелчка DTM добавляет в документ прослушиватель событий:

Добавив в документ одного слушателя, DTM может обнаружить щелчок по любому элементу. Поскольку DTM обнаруживает события щелчка, он может определить, какой элемент щелкнул пользователь и должен ли щелчок запускать какие-либо правила DTM. В нормальных условиях это прекрасно работает. Тем не мение…

Когда прослушиватель событий щелчка выполняется браузером, ему передается объект event. Помимо прочего, у этого event объекта есть метод stopPropagation(). При вызове он не позволяет браузеру продолжать «распространять» событие или, другими словами, продолжать обработку обработчиков событий для последующих элементов в процессе захвата → цели → восходящей цепочки. В нашем примере приложение пользователя DTM добавило прослушиватель событий к элементу ячейки таблицы, а функция прослушивателя вызвала event.stopPropagation(). Это имело следующий эффект:

Поскольку приложение прекращает распространение события, прослушиватели событий для строки таблицы, тела таблицы, таблицы, тела и документа никогда не выполняются. DTM даже не слышит об этом событии. В результате правила, которые должны были выполняться, не выполняются, что приводит к путанице и разочарованию пользователя DTM.

В качестве обходного пути DTM предоставляет флажок, который позволяет пользователю применять прослушиватель событий непосредственно к элементу:

Если в нашем примере этот флажок установлен, DTM добавит дополнительный прослушиватель событий непосредственно в ячейку таблицы:

Таким образом, у DTM теперь есть шанс получить уведомление о событии щелчка, даже если прослушиватель приложения предотвращает распространение события на последующие элементы в иерархии.

Хотя этот подход может (и помог) решить конкретную проблему этого пользователя, он имеет некоторые заметные последствия:

  1. К определенным элементам должны быть добавлены дополнительные прослушиватели событий, что приведет к дополнительной обработке.
  2. DTM должен постоянно опрашивать DOM в поисках новых добавленных элементов, которые относятся к правилам, в которых этот флажок установлен. При обнаружении новых элементов он должен добавить прослушиватель событий к каждому из них.

Если не соблюдать осторожность, это может существенно снизить производительность сайта. К тому же он не очень пуленепробиваемый. Например, хотя мы говорили о event.stopPropagation(), есть еще event.stopImmediatePropagation(), который наносит еще больший ущерб DTM.

Лучший подход с Launch

С Launch пришло время двигаться вперед. Поддержка Internet Explorer 8 была прекращена, и теперь у нас есть фаза захвата для работы. Вместо того, чтобы быть одним из последних, кто узнает о событии, Launch теперь может быть одним из первых. Теперь мы добавляем прослушиватель событий в документ на этапе захвата:

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

Вы заметите, что Launch, в отличие от DTM, не имеет флажка «применить обработчик событий непосредственно к элементу». К счастью, он вам больше не нужен. Мы надеемся, что этот улучшенный подход предотвратит разочарование, с которым пользователи иногда сталкивались при использовании DTM.