代码之家  ›  专栏  ›  技术社区  ›  connexo

后期“手动”将元素升级为定制的内置Web组件

  •  3
  • connexo  · 技术社区  · 6 年前

    我有一个jquery插件(我不想修改),它正在动态创建一个 div 。除此之外,我还有一个Web组件 scrollable-div ,这是一个自定义的内置扩展自 HTMLDivElement 。因为我无法控制 div 是由jquery插件创建的,我需要在创建后和将其添加到DOM后对其进行升级。

    class myDiv extends HTMLDivElement {
      constructor(...args) {
        const self = super(...args);
        self.addEventListener('click', (e) => {
          e.target.textContent = 'clicked'
        })
        return self;
      }
    }
    
    customElements.define('my-div', myDiv, { extends: 'div' });
    
    document.addEventListener('DOMContentLoaded', () => { 
      // this is where I'm trying to turn the div#upgradeMe into a my-div
      upgradeMe.setAttribute('is', 'my-div');
    });
    <div id="upgradeMe">Click me</div>

    只需添加 is="my-div" 属性显然不起作用, div 只是保持正常 HTMLD 。如何以编程方式将已经在DOM中的本机元素升级为自定义的内置Web组件?

    2 回复  |  直到 6 年前
        1
  •  1
  •   Supersharp    6 年前

    这是不可能的,因为元素已经创建为标准 <div> 元素,当分析为 可升级的 (可扩展)由于缺少 is 属性。

    如果已经定义了自定义元素,唯一可能的解决方法是用克隆替换现有的元素(如@barbsan的注释中所建议的那样)。

    捷径:

    1. 创建一个 <template> 要素
    2. 复制div outerHTML 进入其 innerHTML 财产
    3. 用模板的 content 具有 replaceChild()

    class myDiv extends HTMLDivElement {
      constructor(...args) {
        const self = super(...args);
        self.addEventListener('click', (e) => {
          e.target.textContent = 'clicked'
        })
        return self;
      }
    }
    
    customElements.define('my-div', myDiv, { extends: 'div' });
    
    document.addEventListener('DOMContentLoaded', () => { 
      // this is where I'm trying to turn the div#upgradeMe into a my-div
      upgradeMe.setAttribute('is', 'my-div');
      var t = document.createElement( 'template' )
      t.innerHTML = upgradeMe.outerHTML
      upgradeMe.parentElement.replaceChild( t.content, upgradeMe )
    });
    <div id="upgradeMe">Click me</div>

    朊病毒

    分析元素时, 是价值 受到影响 according to the DOM spec :

    元素具有关联的命名空间、命名空间前缀、本地名称、自定义元素状态、自定义元素定义, 是价值 。创建元素时,将初始化所有这些值。

    仅限具有有效 属性标识为可自定义:

    元素自定义元素状态是“未定义”、“失败”、“未自定义”或“自定义”之一。自定义元素状态为“未自定义”或“自定义”的元素称为已定义。自定义元素状态为“自定义”的元素称为自定义。

    因此,如果元素没有 属性在分析时,它将不可自定义。这就是为什么你不能添加 之后属性。

    也在 HTML specs :

    创建自定义元素后,更改 属性不会更改元素的行为,因为它在元素上保存为 是价值 .

    这个 属性仅在元素创建时(分析时)用于初始化 是价值 如果在已经创建元素时更改,则不起作用。在那种意义上 是价值 是只读的。

        2
  •  0
  •   Arjun Yelamanchili    6 年前

    如果你想支持所有的现代浏览器,你就不能自定义内置组件,苹果说他们永远都不会支持is=“” https://github.com/w3c/webcomponents/issues/509#issuecomment-222860736