Делегирование событий в SVG-элементах
Я пытаюсь иметь общий обработчик кликов для всех элементов, которые я добавляю к холсту SVG. Но я не могу делегировать обработчик вновь созданным элементам.
Это код, который я пытался делегировать, но не повезло
$("#floor").on('click','.drawnLine', function() {
//#floor is the SVG Element
//.drawnLine is the <line> element that is added dynamically
console.log($(this).data('index'));
});
Update:
В руководстве jQuery .on()
указано, что
Примечание. Делегированные события не работают для SVG.
Итак, теперь вопрос заключается в любом другом обходном пути для этой проблемы?
Ответы
Ответ 1
Когда jQuery не работает с SVG, вы можете использовать vanilla js. К счастью, каждый браузер, поддерживающий svg, также поддерживает прослушиватели событий. Чистое делегированное событие js не так уродливо:
$("#floor")[0].addEventListener('click', function(e) {
// do nothing if the target does not have the class drawnLine
if (!e.target.classList.contains("drawnLine")) return;
console.log($(this).data('index'));
});
Но вы также можете создать свою собственную функцию для более четкого делегирования ваших событий.
Ответ 2
TL/DR: присоедините прослушиватель событий к родительскому элементу не SVG.
Примечание в документах jQuery несколько вводит в заблуждение.
Делегированные события не работают для SVG.
Вероятно, это должно быть...
Делегированные события не работают , когда слушатель подключен к SVG.
делегирование события jQuery не работает, когда слушатель событий присоединяется к элементу SVG; однако, если вы вместо этого присоединяете слушателя к родительскому элементу SVG, отличному от SVG, распространение событий работает так, как ожидалось, и любые селекторы, которые соответствуют элементам SVG, действительно вызовут функцию обработчика событий.
Прикрепление слушателя к элементу SVG будет не работать:
$("#floor").on('click','.drawnLine', function() {
console.log($(this).data('index'));
});
Но привязка его к родительскому элементу будет работать:
$(document.body).on('click','#floor .drawnLine', function() {
console.log($(this).data('index'));
});
Примечание: одна особенность, которую я заметил, заключается в том, что если целью события является элемент SVG, событие не будет полностью зависеть от document.body
в iOS. Поэтому, если вы хотите, чтобы пользователи iOS могли запускать функцию вашего обработчика, вам нужно прикрепить свой прослушиватель событий к некоторому элементу между ними (например, к элементу div
, в котором находится ваш SVG).