我有一个动态创建div
的jQuery插件(我不想修改)。除此之外,我还有一个Web组件scrollable-div
,它是一个自HTMLDivElement
扩展而成的自定义内置组件。由于我无法控制jQuery插件如何创建div
,因此我需要在创建后以及将其添加到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
只是保持常规HTMLDivElement
。如何以编程方式将DOM中已经存在的本机元素升级为自定义的内置Web组件?
答案 0 :(得分:1)
这是不可能的,因为由于缺少<div>
属性,该元素已经被创建为标准is
元素,并且在解析为 upgradeable (可扩展)时没有被标识
如果已经定义了自定义元素,则唯一可行的解决方法是用克隆替换现有元素(如@barbsan的注释中所建议)。
简而言之:
<template>
元素outerHTML
复制到其innerHTML
属性中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:
元素具有关联的名称空间,名称空间前缀,本地名称,自定义元素状态,自定义元素定义,是值。创建元素时,所有这些值都将初始化。
只有具有有效is
属性的元素才被标识为可自定义:
元素的自定义元素状态是“未定义”,“失败”,“未自定义”或“自定义”之一。据说定义了其自定义元素状态为“未自定义”或“自定义”的元素。定制元素状态为“ custom”的元素被称为定制元素。
因此,如果元素在解析时没有is
属性,则将无法自定义。这就是为什么您以后不能添加is
属性的原因。
也在HTML specs中:
创建自定义元素后,更改 is 属性的值不会更改元素的行为,因为它以 is值保存在元素上。
is
属性仅在元素创建时(在解析时)用于初始化 is值,并且在已创建元素时更改后无效。从这个意义上说,值是只读的。
答案 1 :(得分:0)
如果要支持所有现代浏览器,则无法自定义内置组件,Apple表示它们将永远不支持is =“” https://github.com/w3c/webcomponents/issues/509#issuecomment-222860736