html – 使用不同的子类型创建自定义元素

前端之家收集整理的这篇文章主要介绍了html – 使用不同的子类型创建自定义元素前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我目前正在使用自定义元素(Web组件)实现数据表元素.该表可以具有用于呈现每一行的不同类型的单元格(文本,数字,日期等).

例如

<my-table>
    <my-table-cell-text column="name"></my-table-cell-text>
    <my-table-cell-date column="dob" format="YYYY-MM-DD"></my-table-cell-date>
    <my-table-cell-number column="salary" decimals="2"></my-table-cell-number >
</my-table>

我还有一个所有单元格元素都扩展的MyTableCell类.这适用于共享通用功能,但样式可能很痛苦,因为每个单元格类型都是自己的html标记.目前,我在扩展MyTableCell时添加了一个css类,但是出于参数的考虑,让我说我不想这样做.

理想的解决方案是能够使用is关键字扩展自定义元素,例如< my-table-cell is =“my-table-cell-text”>,but that’s only allowed for built in html elements.

我可以想到解决这个问题的3种方法

>具有类似于< input type =“”>的语法,但这样做的工作要多得多,因为您不再扩展基类,而是创建相同元素的变体,这意味着您需要一种自定义注册方式不同的变体,类似于静态MyTableCell.registerType
>一种可组合的方法,我将一个渲染器元素< my-table-renderer-text>包装在一个通用的< my-table-cell>中.这避免了自定义寄存器方法,但它更难编写并导致更多元素和更多样板代码,这反过来意味着性能损失.
>两者的混合,用户写的< my-table-cell type =“text”>并且单元格在内部使用了document.createElement(‘my-table-rendener-‘type)之类的东西.这保留了选项1的更简单的语法,同时仍然避免使用自定义寄存器方法,但它具有与选项2相同的性能影响.

你能建议更好的选择吗?我错过了什么吗?

解决方法

可以做的是使用< td>类型扩展:
<table is="data-table>
   <tr>
       <td is="data-string">Bob</td>
       <td is="data-date">11/1/2017</td>
       <td is="data-number">44<td>
   </tr>
</table>

所有扩展都共享相同的原型祖先. v0示例:

//common cell
  var cellProto = Object.create( HTMLTableCellElement.protoype )
  cellProto.sharedMethod = function () { ... }

  //typed cell
  var cellStringProto = Object.create( cellProto )
  cellStringProto.specificMethod = function () { ... }
  cellStringProto.sharedMethod = function () { ... }
  document.registerElement( 'data-string',{ prototype: cellStringProto,extends: 'td' } )

这样,所有细胞都延伸相同的细胞.元素,共享一个共同的原型,但有自己的方法实现.

您可以覆盖共享方法,而共享方法可以调用派生原型对象的特定方法.

请在此处查看运行示例:

//table
    var tableProto = Object.create( HTMLTableElement.prototype )
    tableProto.createdCallback = function ()
    {
        console.info( 'data-table created' )
    }
    document.registerElement( 'data-table',{ prototype: tableProto,extends: 'table' } )

    //cell
    var cellProto = Object.create( HTMLTableCellElement.prototype )
    cellProto.createdCallback = function ()
    {
        console.info( 'cell created' )
    }
    cellProto.attachedCallback = function ()
    {
        console.info( 'cell attached' )
        if ( typeof this.renderContent === 'function' ) 
            this.renderContent()
    }

    //cell string
    var cellStringProto = Object.create( cellProto )
    cellStringProto.createdCallback = function ()
    {
        console.info( 'data-string created' )
    }
    cellStringProto.renderContent = function ()
    {
        console.info( 'data-string render' )
        this.innerHTML = '"' + this.textContent.trim() + '"'
    }
    
    document.registerElement( 'data-string',extends: 'td' } )
table {
    border-collapse: collapse ;
}
td,th {
    border: 1px solid gray ;
    padding: 2px
}
<h4>Test Table Extension v0</h4>
<table is="data-table">
    <tr>
        <th>Id      <th>Name    <th>Age
    <tr>    
        <td>1       <td is="data-string">An      <td>20
    <tr>
        <td>2       <td is="data-string">Bob     <td>31

注意:如果您不想要类型扩展,也可以使用自定义标记.我们的想法是拥有一个共同的原型和共享它的不同自定义元素(感谢标准的原型继承).

猜你在找的HTML相关文章