我是Web组件的新手,我正在尝试创建一个非常简单的组件以了解其工作原理。但是我在创建一个问题。我遵循了chrome和Mozilla文档中提到的步骤,但是我仍然无法成功创建一个文档,也找不到问题。
class toolTip extends HTMLElement {
var msg = this.getAttribute('msg');
var value = this.getAttribute('value');
console.log(msg);
console.log(value);
this.innerHTML = msg + ' - ' + value;
}
customElements.define('mdm-tooltip', toolTip);
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>Web Components</title>
</head>
<body>
<mdm-tooltip value='1st tooltip' msg='this the 1st tooltip created using WC'></mdm-tooltip>
<mdm-tooltip value='2nd tooltip' msg='I replaced the existing text'>Im the existing text</mdm-tooltip>
</body>
<script src="main.js" defer></script>
</html>
这是浏览器抛出的错误, 我正在Chrome V67.0.3396.99中运行此代码
答案 0 :(得分:3)
在一个类中,您需要定义实际上包含可执行代码的方法。就您而言,您的代码看起来很像初始化代码,因此构造函数似乎很合适。
class ToolTip extends HTMLElement {
constructor() {
var msg = this.getAttribute('msg');
var value = this.getAttribute('value');
console.log(msg);
console.log(value);
this.innerHTML = msg + ' - ' + value;
}
}
customElements.define('mdm-tooltip', ToolTip);
此外,JavaScript中的一种命名约定是,类应该用小写的大小写形式(以大写字母开头)。
答案 1 :(得分:2)
J.P。十个Berge在大多数情况下是正确的。但是...根据Web组件构造器的规则,您不能也不应做几件事:
https://html.spec.whatwg.org/multipage/custom-elements.html#custom-element-conformance
4.13.2自定义元素构造函数的要求
创作自定义元素构造函数时,作者必须遵守以下符合性要求:
对super()的无参数调用必须是构造函数主体中的第一条语句,以便在运行任何其他代码之前建立正确的原型链和该值。
return语句一定不能出现在构造函数体内的任何地方,除非它是一个简单的提前返回(返回或返回此语句)。
构造函数不得使用document.write()或document.open(type,replace)方法。
不得检查元素的属性和子元素,因为在非升级情况下将不存在元素,而依靠升级将使元素的可用性降低。
该元素不得获得任何属性或子元素,因为这违反了使用createElement或createElementNS方法的消费者的期望。
通常,应将工作尽可能地推迟到connectedCallback进行,尤其是涉及获取资源或渲染的工作。但是,请注意,connectedCallback可以被调用多次,因此,任何真正一次的初始化工作都需要保护措施,以防止其运行两次。
通常,应使用构造函数来设置初始状态和默认值,并设置事件监听器和可能的影子根。
将代码移至connectedCallback
是一个更好的计划:
class ToolTip extends HTMLElement {
connectedCallback() {
var msg = this.getAttribute('msg');
var value = this.getAttribute('value');
console.log(msg);
console.log(value);
this.innerHTML = msg + ' - ' + value;
}
}
customElements.define('mdm-tooltip', ToolTip);
<mdm-tooltip msg="help me" value="10"></mdm-tooltip>
但是您也可以将其更改为以下内容:
class ToolTip extends HTMLElement {
constructor() {
super();
this._msg = '';
this._value = '';
}
static get observedAttributes() {
return [ 'value', 'msg' ];
}
connectedCallback() {
this._render();
}
attributeChangedCallback(attr, oldVal, newVal) {
if (oldVal !== newVal) {
this['_'+attr] = newVal; // This will set either `this._msg` or `this._value`
this._render();
}
}
_render() {
this.innerHTML = `${this._msg} - ${this._value}`;
}
}
customElements.define('mdm-tooltip', ToolTip);
setTimeout(() => {
var el = document.querySelector('mdm-tooltip');
el.setAttribute('value', 'Free');
el.setAttribute('msg', 'I like getting stuff for');
}, 1000);
<mdm-tooltip msg="Help Me" value="10"></mdm-tooltip>
在此示例中,我们使用observedAttributes
和attributeChangedCallback
来查看value
或msg
属性何时更改。完成后,我们将重新渲染组件。
您还可以在设置值时使用属性:
class ToolTip extends HTMLElement {
constructor() {
super();
this._msg = '';
this._value = '';
}
static get observedAttributes() {
return [ 'value', 'msg' ];
}
connectedCallback() {
this._render();
}
attributeChangedCallback(attr, oldVal, newVal) {
if (oldVal !== newVal) {
this['_'+attr] = newVal; // This will set either `this._msg` or `this._value`
this._render();
}
}
get msg() {
return this._msg;
}
set msg(val) {
if (this._msg !== val) {
this._msg = val;
this._render();
}
}
get value() {
return this._value;
}
set value(val) {
if (this._value !== val) {
this._value = val;
this._render();
}
}
_render() {
this.innerHTML = `${this._msg} - ${this._value}`;
}
}
customElements.define('mdm-tooltip', ToolTip);
var el = document.createElement('mdm-tooltip');
el.value = 10;
el.msg = 'Five times two equals';
document.querySelector('.here').append(el);
setTimeout(() => {
var el = document.querySelector('mdm-tooltip');
el.value = [1,2,3];
el.msg = 'I like getting stuff for';
}, 2000);
<div class="here"></div>
在此示例中,我为value
和msg
添加了属性。现在,不必使用setAttribute
,现在可以直接设置属性,并且属性不需要像属性一样是字符串。