У меня возникла проблема, в своем контекстном меню(нажатие ПКМ в квадратном блоке), при нажатии на delete в консоль выводится тег. При каждом нажатии ПКМ, событие запоминается и в консоль выводится много результатов, и с каждым последующим нажатием все больше и больше тегов отобразится. Подскажите, где и какой обработчик удалять, или вынести за пределы функции так, что бы выводился лишь текущий тег, без предыдущих? Заранее спасибо!
Kovalsky, Я добавил несколько элементов в HTML структуру. Суть задачи заключается в следующем, при нажатии на "Delete" выводить в консоль тег на котором я вызывал контекстное меню, тоесть это может быть как список, так и блок, так и картинка(любой элемент внутри белого квадрата). Если я вынесу deleteBtn.addEventListener за пределы function onContextMenu(e) и присвою ивент, то выводить будет тег контекстного меню, а не тег элемента по которому кликал ПКМ
Вы можете например вешать обработчик на клик по всему контекстному меню, а не на каждую конкретную кнопку. И уже этот обработчик будет иметь доступ к нужному элементу именно так, как вы это придумали - через e.target родительского обработчика
Kovalsky, каждая из кнопок должна исполнять различные действия, поэтому и обработчики у них разные должны быть. Просто хочу сначала с этой проблемой разораться, а потом уже дальше двигаться.
Антон, "каждая из кнопок должна исполнять различные действия, поэтому и обработчики у них разные должны быть" - нет. Каждая из кнопок должна исполнять различные действия, и это совсем не значит что у них должны быть разные обработчики. По клику на контекстное меню вы можете отслеживать на какой конкретно элемент был клик и уже в зависимости от этого совершать какие-то действия с исходным элементом.
Kovalsky, Попробовал 2 варианта.
Первый - вынес обработчик клика по кнопке за функцию и заменил кнопку удаления на контекстное меню(добавил для функции свое событие), в таком случае выводит в консоль тег элемента В контекстном меню.
contextMenu.addEventListener('click', function(e) {
if(e.target.parentNode.classList.contains('rename-btn')) {
console.log(`Rename element ${e.target.tagName}`);
} else if(e.target.parentNode.classList.contains('delete-btn')) {
console.log(`Delete element ${e.target.tagName}`);
}
});
Добавил проверку на кнопку по наличии класса(delete/rename), обработчик одинаковый, но действия разные, но event то разный, поэтому и выводит тег контекстного меню, и опять же так как и раньше(чем больше ты вызываешь тем больше раз выводит тег)
Антон, а, так у вас контекстное меню всегда существует, вы его просто скрываете. Ну само собой тогда нет смысла каждый раз вещать обработчик, не правда ли? Если вы его повесили, то значит повторная привязка обработчика к событию приведет к... повторной привязке обработчика к событию)) Раз у вас меню существует всегда, то вы можете например текущий нажатый элемент хранить в переменной, и соответственно при клике на меню выполнять действие с сохраненным элементом.
Kovalsky, Значит нужно сделать 2 вещи
1) Вынести обработчик клика по кнопке вне обработчика вывода контекстного меню.
2) В обработчике вывода контекстного меню сохранять в переменную элемент по которому мы кликнули.
Тогда вопрос, а как нам выводить эту переменную в обработчике клика по контекстному меню, если переменная вне функции будет не доступна?
Антон, ну тут мы пришли к каким-то совсем уже базовым принципам: "а как нам выводить эту переменную в обработчике клика по контекстному меню, если переменная вне функции будет не доступна?" - надо сделать её доступной вне этой функции) То есть нужно сделать так, чтобы эта переменная была доступна и для обработчика пкм по элементу, и для обработчика лкм по меню. В целом вы вроде бы правильно поняли мою идею
Kovalsky, Действительно, про переменную глупый вопрос получился))
Спасибо за помощь, вроде разобрался с этим и все работает как нужно, буду дальше копаться!)
у вас проблема в том что при каждом нажатии вы навешеваете обработчики клика, вынесете все события клика, так чтобы они появлялись один раз (после загрузки html) и проблема уйдет
В таком случае у меня не будет возможности достучатся до элемента по которому производился клик что бы вывести его тег, так как в этом блоке может содержаться любой другой элемент, параграф, картинка. Мы же при клике выводим e.target.tagName