Javascript-форум (https://javascript.ru/forum/)
-   Events/DOM/Window (https://javascript.ru/forum/events/)
-   -   Удаление прослушивания события (https://javascript.ru/forum/events/81708-udalenie-proslushivaniya-sobytiya.html)

VladislavK_ 15.01.2021 14:37

Удаление прослушивания события
 
Здравствуйте, столкнулся с такой проблемой.
Я понимаю, что через removeEventListener можно удалить события, который мы установили через addEventListener.
Но там же есть нюанс, что туда мы передаём функцию:
Ну то есть, если бы писали так:
cell.addEventListener(‘click’, someFunc)
......
cell.removeEventListener(‘click’, someFunc)
Тогда да, оно бы сработало.

Но если будет анонимная функция, то мы не сможем удалить(например)
cell.addEventListener(‘click’, ()=> console.log(‘hello world’))
......
cell.removeEventListener(‘click’, ....?) // тут уже без вариантов

———————————-

Но как поступить, если в ту функцию, которую мы должны выполнять при триггере события, нам нужно передать ещё параметр

Ну то есть:
cell.addEventListener(‘click’, func(param))
Так не сработает(просто сразу же выполнится)

Можно например сделать так:
cell.addEventListener(‘click’, () => func(param)) чтобы переедать параметр
Но как в таком случае нет возможности удалить прослушивание.


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

voraa 15.01.2021 15:18

let param = ...

function somFunc (ev) { handler.call(this, ev, param)}

cell.addEventListener(‘click’, someFunc)
......
cell.removeEventListener(‘click’, someFunc)

рони 15.01.2021 16:01

VladislavK_,
Пожалуйста, отформатируйте свой код!

Для этого его можно заключить в специальные теги: js/css/html и т.п., например:
[html run]
... минимальный код страницы с вашей проблемой
[/html]

О том, как вставить в сообщение исполняемый javascript и html-код, а также о дополнительных возможностях форматирования - читайте http://javascript.ru/formatting.

VladislavK_ 15.01.2021 16:05

private setEvent(): void {
  const cellClick = (cell: Cell) => {
    if (this.occupiedCells.has(cell)) {
      console.log('DESTROY');
    } else {
      console.log('empty');
    }
  };

  this.engine.on(this.shovelNode, 'click', (e) => {
    this.toggleState();
    this.engine.events.click.eventBubbling = !!this.isActive;
    if (this.isActive) {
      this.cells.forEach((cellRow) => cellRow.forEach((cell) => {
        this.engine.on(cell.node, 'click', () => cellClick(cell));
      }));
    } else {
       this.cells.forEach((cellRow) => cellRow.forEach((cell) => {
          this.engine.off(cell.node, 'click', () => cellClick(cell));
        }));
    }
  });
}

this.engine.on и this.engine.off то же самое, что и addEventListener, removeEventListener
this.cells - двумерный массив (игровое поле)
то есть мне надо поставить событие на каждую клетку поля(узел cell в canvas)
но если я сделаю неактиный узел shovel, то тогда удалить все прослушивания

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

VladislavK_ 15.01.2021 16:45

Цитата:

Сообщение от voraa (Сообщение 532770)
let param = ...

function somFunc (ev) { handler.call(this, ev, param)}

cell.addEventListener(‘click’, someFunc)
......
cell.removeEventListener(‘click’, someFunc)

Чуть-чуть пришлось поменять и всё заработало, спасибо большое!)

voraa 15.01.2021 16:57

Попробуйте рассмотреть такой вариант.
Если к каждой ячейке cell добавить еще поле clickHandler, сильно хуже ей не станет
private setEvent(): void {
  const cellClick = (cell: Cell) => {
    if (this.occupiedCells.has(cell)) {
      console.log('DESTROY');
    } else {
      console.log('empty');
    }
  };
 
  this.engine.on(this.shovelNode, 'click', (e) => {
    this.toggleState();
    this.engine.events.click.eventBubbling = !!this.isActive;
    if (this.isActive) {
      this.cells.forEach((cellRow) => cellRow.forEach((cell) => {
	    cell.clickHandler = () => cellClick(cell)
        this.engine.on(cell.node, 'click', cell.clickHandler);
      }));
    } else {
       this.cells.forEach((cellRow) => cellRow.forEach((cell) => {
          this.engine.off(cell.node, 'click', cell.clickHandler);
        }));
    }
  });
}


Я, конечно не совсем представляю, что такое на самом деле
this.engine.on(cell.node, 'click', () => cellClick(cell));
Но если это просто
cell.node.addEventListener(‘click’, () => cellClick(cell))

то можно просто
cell.node.onclick = () => cellClick(cell)
и
cell.node.onclick = null


Часовой пояс GMT +3, время: 11:03.