-2

How could I remove event listeners of for example $('table td') but not its child's elements event listeners? (I have a table with button in its cells) I tried it with .off() but it doesn't work.

edit: For example I have a table cell with some text and a button in it. Now td and button have their own event listeners. I want to remove only the event listener of td without removing event listener of button. I know I could just add event listener back to the button after it's removed, but that solution would cause a lot of problems in my case.

YakovL
  • 7,557
  • 12
  • 62
  • 102
theg
  • 469
  • 2
  • 6
  • 21
  • 2
    Can you create a demo of what you are currently working with please or at least include the relevant source code? Thank you. – NewToJS Mar 02 '19 at 22:22
  • 1
    Using `.off()` on an element like `td` does not actually remove the event handlers of the childs... Have a look at this [CodePen](https://codepen.io/Bes7weB/pen/gErZKp?editors=1111) – Louys Patrice Bessette Mar 03 '19 at 03:00

2 Answers2

0

I'm guessing you've seen answers such as this one, since you mention not removing event listeners on child elements. Of course doing a deep clone won't work, but what can work is to do a shallow clone, and then transfer the child nodes to the clone. It's a little more work, but it will do what you want.

The main work is in the setTimeout, all the rest is really just setup.

Here I'm attaching two click event listeners: one to the button and one to the container div. before the 5 second setTimeout, clicking the button will fire both listeners (so you'll see console logs for both BUTTON and DIV). After the timer, you'll still see the BUTTON event.

var rem = document.getElementById('rem');
var btn = document.getElementById('btn');
function onClick(e) {
  var t = e.currentTarget
  console.log(t.tagName);
}
rem.addEventListener('click', onClick);
btn.addEventListener('click', onClick);

setTimeout(() => {
  console.log('removing events from div');

  // shallow clone
  var rem2 = rem.cloneNode(false);

  // make and extract range to doc fragment 
  // for all contents of original div
  var range = document.createRange(); 
  range.setStartBefore(rem.firstChild);
  range.setEndAfter(rem.lastChild);
  var documentFragment = range.extractContents();

  // append doc fragment to clone
  // insert clone and remove old div
  rem2.appendChild(documentFragment);
  document.body.insertBefore(rem2, rem);
  rem.remove();
}, 5000);
<div id='rem'>
  <h3>Heading</h3>
  <button id='btn'>click me</button>
  <p>paragraph <b>bold</b> stuff</p>
</div>
David784
  • 7,031
  • 2
  • 22
  • 29
0

I finally got it working using namespaces as on('click.namespace', function(){...}). Thank you for help guys!

theg
  • 469
  • 2
  • 6
  • 21