I am trying out using custom elements. I want to use JS to create the elements and add them to the DOM. If I use this all in one file with a basic html page all works fine.
'use strict';
class FlashCard extends HTMLElement {
constructor(cardSet) {
super();
this.cardSet = cardSet;
this.cardNumber = 0;
}
connectedCallback() {
this.id = 'flashcard';
this.style.cursor = 'pointer';
this.render(this.cardSet);
this.addEventListener('click', this.onClick);
}
render() {
this.innerHTML = this.cardSet[this.cardNumber];
}
onClick() {
let deckSize = this.cardSet.length;
if (this.cardNumber === deckSize-1) {
this.cardNumber = 0;
} else {
this.cardNumber++;
};
this.render();
}
}
customElements.define('flash-card', FlashCard);
document.addEventListener('DOMContentLoaded', function() {
let card = new FlashCard(['a', 'b', 'c', 'd']);
document.getElementsByTagName('body')[0].appendChild(card);
});
My problems start when I try to split the code into separate files.
'use strict';
export default class FlashCard extends HTMLElement {
constructor(cardSet) {
super();
this.cardSet = cardSet;
this.cardNumber = 0;
}
connectedCallback() {
this.id = 'flashcard';
this.style.cursor = 'pointer';
this.render(this.cardSet);
this.addEventListener('click', this.onClick);
}
render() {
this.innerHTML = this.cardSet[this.cardNumber];
}
onClick() {
let deckSize = this.cardSet.length;
if (this.cardNumber === deckSize-1) {
this.cardNumber = 0;
} else {
this.cardNumber++;
};
this.render();
}
}
customElements.define('flash-card', FlashCard);
And In a separate file
import FlashCard from './flashcard';
document.addEventListener('DOMContentLoaded', function() {
let card = new FlashCard(['a', 'b', 'c', 'd']);
document.getElementsByTagName('body')[0].appendChild(card);
});
I then transpile the javascript because of the export/import using a npm script in the package.json file
"watch": "watchify elements/*.js -t babelify --plugins transform-es2015-classes
-o js/bundle.js --debug --verbose",
The error I get in Chrome 55 is
Failed to construct 'HTMLElement': Please use the 'new'
operator, this DOM object constructor cannot be called as a function.
So the transpiled code is trying to call the constructor method on HTMLElement object, but the method is not a function in this case.
My question is how do I split up my code into separate files as I am attempting to above but in a way the transpiler can interpret correctly?
You should try to use Reflect.construct() instead of super() in the constructor() method.
Also, you can try this plugin that is supposed to fix the issue (I didn't test it).