MDN’s new design is in Beta! A sneak peek: https://blog.mozilla.org/opendesign/mdns-new-design-beta/

自定义元素(Custom Elements)

自定义元素是一种用于创建自己的自定义HTML元素的功能。他们可以有自己的脚本行为和CSS样式。它们是Web组件的一部分,但也可以自己单独使用。

注意:自定义元素最近才稳定,并且MDN的某些部分仍包含来自旧规范草案的过时API的文档。

可能不清楚为什么创建新的自定义元素能力,毕竟现在已经可以创建一个标签名称像<mytag>, 并用CSS设置其样式,然后使用脚本给它附加行为。自定义元素的一个优势是它们的生命周期反应,这允许将行为附加到新元素的“生命周期”的不同部分。例如,当元素被插入到DOM中时 (“已连接”) 可以附加某个行为, 及当它从DOM中移除时 (“断开连接”) 或者 当其属性改变时, 附加不同的行为。

启用自定义元素关键在于 Document.registerElement() 方法,此方法向浏览器注册一个新元素,该元素默认使用 HTMLElement 接口(如果您创建了类似<mytag>的标签,但不注册,它将会使用 HTMLUnknownElement接口。您也可以在例如 <button> 这样的原生元素的基础上创建自定义元素,不过如此一来就不能使用自定义标签名,比如 <my-button> ,而要使用 <button is="my-button"> 这样的语法了)。

生命周期回调(Lifecycle callbacks)

自定义元素可以使用以下生命周期回调函数:

  • createdCallback - 注册元素时执行
  • attachedCallback - 元素插入DOM时执行
  • detachedCallback - 元素被移除DOM时执行
  • attributeChangedCallback - 元素的属性被增、删、改时执行

示例

自定义元素可用 Object.prototypeShadowRoot 相关技巧创建,如下 jsfiddle 所示:

在ES2015中创建自定义元素的一种简单方法是:使用 "Class" 而非 "ProtoType" ,此时可以不使用 "ShadowRoot"。

HTML文件:

If nothing appeared below, then your browser not supporting Custom Elements.
<x-product data-name="Ruby" data-img="https://s3-us-west-2.amazonaws.com/s.cdpn.io/4621/ruby.png" data-url="http://example.com/1"></x-product>
<x-product data-name="JavaScript" data-img="https://s3-us-west-2.amazonaws.com/s.cdpn.io/4621/javascript.png" data-url="http://example.com/2"></x-product>
<x-product data-name="Python" data-img="https://s3-us-west-2.amazonaws.com/s.cdpn.io/4621/python.png" data-url="http://example.com/3"></x-product>

JS文件:

// Create a new object based of the HTMLElement prototype
var XProductProto = Object.create(HTMLElement.prototype);

// Set up the element.
XProductProto.createdCallback = function() {
    // Create a Shadow Root
    var shadow = this.createShadowRoot();

    // Create a standard img element and set it's attributes.
    var img = document.createElement('img');
    img.alt = this.getAttribute('data-name');
    img.src = this.getAttribute('data-img');
    img.width = '150';
    img.height = '150';
    img.className = 'product-img';

    // Add the image to the Shadow Root.
    shadow.appendChild(img);

    // Add an event listener to the image.
    img.addEventListener('click', function(e) {
        window.location = this.getAttribute('data-url');
    });
  
    // Create a link to the product.
    var link = document.createElement('a');
    link.innerText = this.getAttribute('data-name');
    link.href = this.getAttribute('data-url');
    link.className = 'product-name';

            // Add the link to the Shadow Root.
    shadow.appendChild(link);
};

// Register the new element.
var XProduct = document.registerElement('x-product', {
    prototype: XProductProto
});

CSS文件:

下例使用的 ::Shadow 已被弃用(deprecated)。

body {
  background: #F7F7F7;
}

x-product {
  display: inline-block;
  float: left;
  margin: 0.5em;
  border-radius: 3px;
  background: #FFF;
  box-shadow: 0 1px 3px rgba(0,0,0,0.25);
  font-family: Helvetica, arial, sans-serif;
  -webkit-font-smoothing: antialiased;
}

x-product::shadow .product-img {
  cursor: pointer;
  background: #FFF;
  margin: 0.5em;
}

x-product::shadow .product-name {
  display: block;
  text-align: center;
  text-decoration: none;
  color: #08C;
  border-top: 1px solid #EEE;
  font-weight: bold;
  padding: 0.75em 0;
}

这是上例的可执行版本:

规范(Specification)

自定义元素在下列规范中定义:

规范 状态 评论
Custom Elements Working Draft  

资源

文档标签和贡献者

 此页面的贡献者: xgqfrms-GitHub, jchnxu
 最后编辑者: xgqfrms-GitHub,