0

I want to listen to click events on elements that are dynamically created and aren't appended. See this example:

document.addEventListener('click', function(e){
  if(e.target.tagName == 'BUTTON'){
    console.log('Click');
  }
});
document.createElement('button').click();
<button>Test</button>

The listener isn't called when creating an element and using the click method on it.

Why is this and how can I listen to those events?

Thanks!

J. Doe
  • 35
  • 3

1 Answers1

0

As mentioned in comments, either overwrite HTMLButtonElement.prototype.click:

const nativeClick = HTMLButtonElement.prototype.click;
HTMLButtonElement.prototype.click = function(...args) {
  console.log('Click');
  nativeClick.apply(this, args);
};

document.createElement('button').click();

Or, a slightly different (and less efficient) method would be to overwrite Document.prototype.createElement such that newly created buttons get listeners attached to them:

const nativeCreateElement = Document.prototype.createElement;
Document.prototype.createElement = function(...args) {
  const createdElement = nativeCreateElement.apply(this, args);
  if (typeof args[0] === 'string' && args[0].toLowerCase() === 'button') {
    createdElement.addEventListener('click', () => {
      console.log('Click');
    });
  }
  return createdElement;
}

document.createElement('button').click();

Note that overwriting important built-in objects and methods like this is very hacky and isn't something to be used in serious production code - it's only something to consider when you have no other options, such as in the unusual environment of a userscript.

CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
  • Thanks! My question was marked as duplicate at first by someone who didn't fully read it. It's for a userscript so that's fine. By the way it should work on all elements not just buttons. The button was just for the example. – J. Doe Dec 22 '18 at 23:32