Форум программистов, компьютерный форум, киберфорум
JavaScript для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.67/18: Рейтинг темы: голосов - 18, средняя оценка - 4.67
29 / 26 / 18
Регистрация: 02.04.2015
Сообщений: 316

Как добавить свой (дополнительный) обработчик события элементу, которого пока нет на форме

11.04.2020, 00:17. Показов 3758. Ответов 6
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Вечер добрый.
Есть форма партнёра, которая посредством JS размещается на страницах моего сайта.
При нажатии на кнопку-партнёрку с их сервера качается форма, открывается на моём сайте, посетитель заполняет в ней данные и, по нажатии кнопки, происходит отправка данных на сервер партнёра + закрытие их формы.
Кнопка отправки (на самом деле там <input type="submit" id="formSubmit">) имеет свой уникальный id.
Мне нужно добавить свой обработчик клика по этому элементу (записать данные в собственную БД).
В простом варианте я видел себе это таким образом:
JavaScript
1
2
3
4
5
var formSubmit = document.getElementById('formSubmit');
formSubmit .addEventListener("click", clickFormSubmit());
function clickFormSubmit(){
   // Тут сохраняю всё, что мне нужно
}
Проблема в том, что нужная мне кнопка появляется даже не в первой, а во второй форме, скачиваемой с сайта-партнёра:
Сначала на моём сайте есть только ссылка на их скрипт и элемент, при клике на который происходит скачивание и вывод первой формы с сайта-партнёра.
На первой форме выбор стратегии из 3'х вариантов - пользователь кликает на заинтересовавший его вариант.
После клика пользователя на одном из вариантов, происходит скачивание второй формы с сайта партнёра.
На этой ("целевой") форме пользователь заполняет свои реквизиты и нажимает кнопку отправки.

Вот это нажатие я хочу "перехватить", сохранить себе в базу введённые пользователем реквизиты, и уже после этого - отправить эти данные на сайт партнёра.

Ещё раз, это не оплата онлайн и прочие ништяки: форма с сайта партнёра "открывается" даже не в ифрейме, а обычным <div>.
Проблема в том, что даже на момент нажатия пользователем "моей" кнопки, открывающей (скачивающей и открывающей) форму с сайта партнёра, в моём документе пока отсутствует необходимый мне элемент с id="formSubmit". Поэтому когда я пытаюсь найти элемент с таким id, мне по понятным причинам, возвращается undefined (соответственно - я не могу назначить обработчик события для undefined-элемента).

Пока что придумал костыль через установку таймера: если через n времени кнопка появилась - назначить свой обработчик. Причём проверять нужно наличие сразу 2'х кнопок, при появлении кнопки "Отмена" - вешать доп.обработчик на её клик, который разрушит таймер.

Сама идея добавления обработчиков событий через таймеры мне не нравится. Поэтому не стал её пока что реализовывать, а решил взять таймаут и послушать что скажет купечество: какие еще есть варианты назначения слушателя событий для элементов, которых пока что нет в документе (но которые могут в нём появиться)?

Добавлено через 37 минут
Нагуглил немного о Делегировании событий.
Правильно ли я понимаю, что если добавлю свой:
JavaScript
1
2
3
4
5
6
document.addEventListener('click', clickFormSubmit(event));
function clickFormSubmit(event){
   if(event.target.id == 'formSubmit'){
      // То тут я, теоретически, должен отловить именно клик на интересующем меня элементе... ??!
   }
}
Понятно, что опущены проверки наличия id и вообще, стоит прицепиться не ко всему документу, а ко всем input (а то, если получится, и вовсе именно к input type="submit").

Меня интересует сама концепция: оно живое/работоспособное? Благодаря навешиванию собственного обработчика для "предка" - этот обработчик будет назначен всем новым объектам, не существовавшим в документе на момент присвоения обработчика предку?! Стоит тратить время на проверку?! ))
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
11.04.2020, 00:17
Ответы с готовыми решениями:

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

Можно ли как-то создать обработчик события, которого нет среди стандартных?
Проходил в августе производственную практику на одном предприятии. Был один такой момента, когда нужно было создать обработчик для события,...

Как назначить горячую клавишу на обработчик элемента, которого нет на форме?
Пишу простой текстовый редактор. Есть форма, на которой три Label (lblParagraph01, lblParagraph02, lblParagraph03), на каждый назначен...

6
29 / 26 / 18
Регистрация: 02.04.2015
Сообщений: 316
12.04.2020, 23:16  [ТС]
Уж полночь близится, а Германа всё нет...
То ли знаний основ не хватило, то ли еще чего-то, но через предка достучаться до пока еще не существующего на странице элемента не получилось.
Пока что вышел из ситуации установкой рекурсивного таймера, который включаю по кнопке открытия формы-партнёрки и "выключаю" (не продолжаю) при нахождении в документе нужной мне кнопки, выглядит это примерно так:
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function check_formSubmit(){
    if(document.getElementById('formSubmit')){
        return true;
    }
    return false;
}
 
function save_order(){
    // Сохраняю нужные мне реквизиты
}
 
function buyOnPartner(){
    let timerId = setTimeout(function tick() {
        if(check_formSubmit()){
            let formSubmit = document.getElementById('formSubmit');
            formSubmit.addEventListener('click', save_order);
        }else{
            timerId = setTimeout(tick, 500);
        }
    }, 500);
}
С одной стороны - оно работает. Т.е. свою задачу я вот таким вот костылём - выполнил.
С другой стороны, давным-давно мне вбили в голову, что использование всякого рода sleep | delay и прочих Timer, с высокой степенью вероятности свидетельствует об архитектурном просчёте.

С удовольствием перепишу свой метод, если найдётся кто-то, кто ткнёт меня носом в теорию, описывающую как правильно назначить своего доп.слушателя (addEventListener) для не существующего в документе (пока еще) элемента.
0
738 / 543 / 416
Регистрация: 17.09.2015
Сообщений: 1,601
13.04.2020, 08:10
а какой скрипт отрисовывает партнерскую форму? вот туда и нужно добавлять обработчик для кнопки формы
1
29 / 26 / 18
Регистрация: 02.04.2015
Сообщений: 316
13.04.2020, 09:01  [ТС]
Цитата Сообщение от LFC Посмотреть сообщение
вот туда и нужно добавлять обработчик для кнопки формы
- Не, нельзя, потому как этот скрипт хостится на сервере партнёра и изменяется им же по настроению/необходимости.
В общем у меня есть полный доступ к своему сайту/серверу, но нет доступа к партнёрскому (могу, конечно, разместить его локально и отредактировать, но тогда прийдётся следить за выходом новых редакций и своевременно обновлять самому).
0
Эксперт JS
2463 / 1769 / 625
Регистрация: 11.07.2016
Сообщений: 4,067
13.04.2020, 11:49
Цитата Сообщение от ИмяПользователя Посмотреть сообщение
в моём документе пока отсутствует необходимый мне элемент с id="formSubmit". Поэтому когда я пытаюсь найти элемент с таким id, мне по понятным причинам, возвращается undefined (соответственно - я не могу назначить обработчик события для undefined-элемента)
Смотрите делегирование событий.
Если вы хотите повесить обработчик событий на динамические элементы (которых ещё нет на странице, но они могут появляться и исчезать), то применяется делегирование. Идея в том, чтобы повесить обработчик события не на конкретный элемент, а на его предка. Затем при срабатывании события вы смотрите на event.target и, если это нужный элемент, обрабатываете. На jQuery это делается просто:
JavaScript
1
$('.some-parent-element').on('click', '.dynamic-element', callback);
Событие срабатывает при каждом клике на .some-parent-element. Если элемент в event.target содержит класс dynamic-element, вызывается callback в контексте элемента .dynamic-element.
Подробнее можете найти в гугле.
Пример: https://codepen.io/Balanaar/pen/qBOdxzG
HTML5
1
2
<ul class="list"></ul>
<button>Добавить</button>
JavaScript
1
2
3
4
5
6
7
8
let i = 0;
$('button').on('click', function() {
  $('.list').append(`<li>Элемент списка ${++i}</li>`);
});
 
$('.list').on('click', 'li', function() {
  alert(this.innerText);
});
1
 Аватар для diadiavova
7259 / 2606 / 744
Регистрация: 11.04.2015
Сообщений: 4,150
Записей в блоге: 43
13.04.2020, 11:58
Лучший ответ Сообщение было отмечено ИмяПользователя как решение

Решение

Цитата Сообщение от ИмяПользователя Посмотреть сообщение
То ли знаний основ не хватило, то ли еще чего-то, но через предка достучаться до пока еще не существующего на странице элемента не получилось.
Повесить обработчик на вмещающий контейнер - идея, которая приходит в первую очередь, но, к сожалению, это не всегда срабатывает, особенно если на элементе уже есть обработчик и автор кода обработчика позаботился о том, чтобы событие дальше не всплывало. Вот пример
HTML5
1
2
3
4
5
    <div id="container">
        <div id="target1">target1</div>
        <div id="target2">target2</div>
 
    </div>
Теперь вешаем обработчик на контейнер, который будет отслеживать клики по вложенным дивам и сообщать, по какому был сделан клик
JavaScript
1
2
3
4
        document.getElementById("container").addEventListener("click", function (evt)
        {
            alert(evt.target.id + " clicked");
        });
Все работает, но если теперь на один из вложенных дивов повесить вот это
JavaScript
1
2
3
4
        document.getElementById("target1").addEventListener("click", function (evt)
        {
            evt.stopPropagation();
        });
То клики по нему уже не будут отслеживаться в контейнере.
Здесь, как мне кажется, наиболее разумным было бы посмотреть в сторону MutationObserver: наблюдатель за изменениями. Он сообщит об изменениях в интересующей области, далее надо будет проверить появилось ли то что надо и если да, то вешать обработчик непосредственно куда надо.
2
29 / 26 / 18
Регистрация: 02.04.2015
Сообщений: 316
13.04.2020, 15:46  [ТС]
Цитата Сообщение от Balanaar Посмотреть сообщение
Смотрите делегирование событий.
- Спасибо - смотрел, что-то пошло не так. Я мог сам накосячить с указанием прямого вызова метода в addEventListener, вместо только его имени, а может имел место быть случай, описанный ниже дядей Вовой.
Поэтому хочу подробней изучить и переписать именно как посоветовал дядя Вова, с использованием MutationObserver.

Всем спасибо, направление обозначено, дальше дело техники! ))

Добавлено через 2 часа 13 минут
Цитата Сообщение от diadiavova Посмотреть сообщение
Здесь, как мне кажется, наиболее разумным было бы посмотреть в сторону MutationObserver: наблюдатель за изменениями. Он сообщит об изменениях в интересующей области
- Жаль, что нельзя 2 раза "спасибо" жмакнуть! Просто магия!! )))
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
13.04.2020, 15:46
Помогаю со студенческими работами здесь

Как сделать свой обработчик события для нескольких TextBox
У меня есть метод, который не позволяет писать в textBox'ы ничего кроме цифр. public static int n; public static string s; ...

Как добавить код в обработчик события?
Друзья! Здесь написано, как http://msdn.microsoft.com/ru-ru/library/zwwsdtbk.aspx Делаю всё, как сказано. Дохожу жо пятого пункта ...

Как добавить обработчик события для кнопки?
Доброго времени суток. Как добавить обработчик событи для кнопки. Стандартно пробовал: два раза на кнопке нажимал, добавляло, вот...

Как добавить обработчик события IDocument2.onclick
Как добавить обработчик события IDocument2.onclick на C#

Свой обработчик события
Допустим в момент модельного времени t0 я хочу запустить свой собственный обработчик события, представленный неким объектом типа Runnable....


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Новые блоги и статьи
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip Сканируйте QR-код на мобильном и вы увидите, что появится джойстик для управления главным героем. . . .
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка библиотек: SDL3, Box2D, FreeType, SDL3_ttf, SDL3_mixer и SDL3_image из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru