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.
var self = Reflect.construct( HTMLElement, [], Flashcard )
self.cardSet = cardSet
...
return self
Also, you can try this plugin that is supposed to fix the issue (I didn't test it).