您如何解决克隆模板丢失元素引用的问题?
How do you get around Cloned Templates losing Element References?
我注意到 hyperHTML 保留了我对元素的引用:
let div = document.createElement("div");
div.textContent = "Before Update";
hyperHTML.bind(document.body)`static1 - ${div} - static2`;
div.textContent = "After Update";
上面会生成一个页面,上面写着:
static1 - After Update - static2
据我了解,hyperHTML 最终会克隆一个 HTML <tempate>
元素来呈现最终输出。但是,在克隆 HTML 模板(如上例中的变量 "div" )时,您通常不会丢失引用吗?
因此,在初始渲染中,hyperHTML 是否会在克隆 HTML 模板后以某种方式将克隆的元素替换为原始元素?
我认为它是这样工作的:
- 创建原始模板文字的 HTML 模板,同时
用注释替换所有插值。
- 克隆 html 模板并留下评论。
- 从最初收到的每个插值中制作元素或文档片段
- 用其 processed 插值替换克隆中的每个评论。
这是正确的吗?
我不确定这里的问题是什么,但也有一个 documentation page, and various examples 理解如何使用 hyperHTML,这与您使用它的方式不完全相同。
事实上,那里不需要任何参考,因为 hyperHTML 是声明性的,所以您宁愿写:
function update(text) {
var render = hyperHTML.bind(document.body);
render`static1 - <div>${text}</div> - static2`;
}
并在需要时随时致电 update("any text")
。
Here's how I think it works ... Is this correct?
不,不是。 hyperHTML 不会按照您描述的方式克隆任何内容,它会将每个唯一的模板标签关联一次,将一个经过清理的版本与输出关联起来,并找出其中的所有插值孔。
执行此操作的库部分称为 domtagger,每个模板文字的映射基于标准事实,即每个范围都是唯一的:
const templates = [];
function addTemplate(template, value) {
templates.push(template);
return template.join(value);
}
function asTemplate(value) {
return addTemplate`number ${value}!`;
}
asTemplate(1);
asTemplate(2);
asTemplate(Math.random());
templates[0] === templates[1]; // true
templates[1] === templates[2]; // true
// it is always the same template object!
在那之后,任何其他使用一次完全相同的标签模板的元素都将具有该片段的克隆,其中包含用于查找漏洞的地图和一些复杂的逻辑,以避免替换任何已知的内容,例如文本、属性、事件,或任何其他类型的节点。
hyperHTML 从不删除注释,它使用这些作为 pin,然后在需要更新任何内容时使用 domdiff 最终更新与这些 pin 相关的节点。
Domdiff 是 petit-dom 算法的 vDOM-less 实现,它又基于 E.W Myers 的“An O(ND ) 差分算法及其变体" paper.
只要空洞中有 DOM 个节点,hyperHTML 就会理解并用这些节点填充这些空洞。如果您重复传递同一个节点,hyperHTML 将不会做任何事情,因为它充满了算法和智能决策,所有这些都在文档中进行了描述,以从其抽象中获得最佳性能。
所有这些以及更多内容,针对任何浏览器进行了规范化,使 hyperHTML 在缩小和 gzip 后重量大约为 7K,它还提供:
- 自定义元素,例如通过 onconnected/disconnected 听众
的钩子
- 轻量级组件通过hyperHTML.Component
- 作为内容或通过线路进行 SVG 操作
- 通过 HyperHTMLElement 轻松定义自定义元素 class
综上所述,如果您需要这些简化并且不想重新发明轮子,我建议您尝试一下。
如果您只是想了解它的工作原理,则无需进行任何假设,因为该项目是完全开源的。
到目前为止,我从你在这里和那里的问题中读到的全部内容是,你只是相信理解它是如何工作的,所以我希望在这个回复中我已经把你需要完全理解的所有遗漏部分放在一起它。
您想编写自己的 lit/hyperHTML 库吗?继续吧,也可以随意使用 domtagger 或 domdiff 库,很少有人已经在这样做了。
我注意到 hyperHTML 保留了我对元素的引用:
let div = document.createElement("div");
div.textContent = "Before Update";
hyperHTML.bind(document.body)`static1 - ${div} - static2`;
div.textContent = "After Update";
上面会生成一个页面,上面写着:
static1 - After Update - static2
据我了解,hyperHTML 最终会克隆一个 HTML <tempate>
元素来呈现最终输出。但是,在克隆 HTML 模板(如上例中的变量 "div" )时,您通常不会丢失引用吗?
因此,在初始渲染中,hyperHTML 是否会在克隆 HTML 模板后以某种方式将克隆的元素替换为原始元素?
我认为它是这样工作的:
- 创建原始模板文字的 HTML 模板,同时 用注释替换所有插值。
- 克隆 html 模板并留下评论。
- 从最初收到的每个插值中制作元素或文档片段
- 用其 processed 插值替换克隆中的每个评论。
这是正确的吗?
我不确定这里的问题是什么,但也有一个 documentation page, and various examples 理解如何使用 hyperHTML,这与您使用它的方式不完全相同。
事实上,那里不需要任何参考,因为 hyperHTML 是声明性的,所以您宁愿写:
function update(text) {
var render = hyperHTML.bind(document.body);
render`static1 - <div>${text}</div> - static2`;
}
并在需要时随时致电 update("any text")
。
Here's how I think it works ... Is this correct?
不,不是。 hyperHTML 不会按照您描述的方式克隆任何内容,它会将每个唯一的模板标签关联一次,将一个经过清理的版本与输出关联起来,并找出其中的所有插值孔。
执行此操作的库部分称为 domtagger,每个模板文字的映射基于标准事实,即每个范围都是唯一的:
const templates = [];
function addTemplate(template, value) {
templates.push(template);
return template.join(value);
}
function asTemplate(value) {
return addTemplate`number ${value}!`;
}
asTemplate(1);
asTemplate(2);
asTemplate(Math.random());
templates[0] === templates[1]; // true
templates[1] === templates[2]; // true
// it is always the same template object!
在那之后,任何其他使用一次完全相同的标签模板的元素都将具有该片段的克隆,其中包含用于查找漏洞的地图和一些复杂的逻辑,以避免替换任何已知的内容,例如文本、属性、事件,或任何其他类型的节点。
hyperHTML 从不删除注释,它使用这些作为 pin,然后在需要更新任何内容时使用 domdiff 最终更新与这些 pin 相关的节点。
Domdiff 是 petit-dom 算法的 vDOM-less 实现,它又基于 E.W Myers 的“An O(ND ) 差分算法及其变体" paper.
只要空洞中有 DOM 个节点,hyperHTML 就会理解并用这些节点填充这些空洞。如果您重复传递同一个节点,hyperHTML 将不会做任何事情,因为它充满了算法和智能决策,所有这些都在文档中进行了描述,以从其抽象中获得最佳性能。
所有这些以及更多内容,针对任何浏览器进行了规范化,使 hyperHTML 在缩小和 gzip 后重量大约为 7K,它还提供:
- 自定义元素,例如通过 onconnected/disconnected 听众 的钩子
- 轻量级组件通过hyperHTML.Component
- 作为内容或通过线路进行 SVG 操作
- 通过 HyperHTMLElement 轻松定义自定义元素 class
综上所述,如果您需要这些简化并且不想重新发明轮子,我建议您尝试一下。
如果您只是想了解它的工作原理,则无需进行任何假设,因为该项目是完全开源的。
到目前为止,我从你在这里和那里的问题中读到的全部内容是,你只是相信理解它是如何工作的,所以我希望在这个回复中我已经把你需要完全理解的所有遗漏部分放在一起它。
您想编写自己的 lit/hyperHTML 库吗?继续吧,也可以随意使用 domtagger 或 domdiff 库,很少有人已经在这样做了。