1

I would like to create a HTML custom element extending HTMLInputElement and define its default behavior for events such as focus, change, click, keypress etc.

After giving up on CustomElementV1 (the super() call producing an "Illegal constructor" error), I have tried with the CustomElementV0 approach:

var Xinput = Object.create(HTMLInputElement.prototype);
Xinput.createdCallback = ()=>{
  this.addEventListener('change',(e)=>{
    console.info("field changed", e.target);
  });
};
var Xi = document.registerElement('x-input', { prototype: Xinput, extends: 'input'});

The node is created later:

var n = new Xi();

I would have expected that the this variable in the createdCallback function refers to the DOM node that has been created when doing "new Xi()". However, it refers to the Window object and, as a consequence, the change event is registered multiple times and fires once for each element created: Changing a single field will trigger the change event as many times as there are x-input elements in the DOM.

I have observed this behavior with Chrome v54 - v57.

What is the correct way to achieve the expected behavior (i.e. the event firing only once)?

dogmeat
  • 13
  • 3
  • 3
    [Arrow Functions and This](https://stackoverflow.com/questions/28798330/arrow-functions-and-this), [When should I use Arrow functions in ECMAScript 6?](https://stackoverflow.com/questions/22939130/when-should-i-use-arrow-functions-in-ecmascript-6) – Andreas Dec 17 '16 at 11:14
  • It's not at all an "exact duplicate of an existing question" – Supersharp Dec 17 '16 at 13:10
  • I've been getting used to using the arrow function without thinking about the implications. – dogmeat Dec 18 '16 at 09:00
  • 1
    So thanks to Andreas and Supersharp for pointing me to the answers. As for the question whether this is a duplicate or not: If this is a duplicate then all questions arising from insufficient programming skills should be marked as duplicates. I'll leave this question to the smart guys. – dogmeat Dec 18 '16 at 09:03

1 Answers1

0

As suggested by the link in comment, you should not use an arrow function to define the createdCallback method because it won't change the this value.

Instead, use the "classical" function() syntax:

Xinput.createdCallback = function () {
  this.addEventListener('change',e=>
    console.info("field changed", e.target)
  );
};
Supersharp
  • 23,488
  • 6
  • 68
  • 109