创建Web组件时出错

时间:2018-07-15 13:03:28

标签: html5 web-component

我是Web组件的新手,我正在尝试创建一个非常简单的组件以了解其工作原理。但是我在创建一个问题。我遵循了chromeMozilla文档中提到的步骤,但是我仍然无法成功创建一个文档,也找不到问题。

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中运行此代码

This is error browser throws

2 个答案:

答案 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>

在此示例中,我们使用observedAttributesattributeChangedCallback来查看valuemsg属性何时更改。完成后,我们将重新渲染组件。

您还可以在设置值时使用属性:

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>

在此示例中,我为valuemsg添加了属性。现在,不必使用setAttribute,现在可以直接设置属性,并且属性不需要像属性一样是字符串。