Делегирование событий в 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'));
});
</line>

Update: В руководстве jQuery .on() указано, что

Примечание. Делегированные события не работают для SVG.

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

2 ответа

Когда 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'));
});

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


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

licensed under cc by-sa 3.0 with attribution.