我注意到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模板后以某种方式将克隆的元素替换为其原始元素?
这是我认为的工作方式:
这正确吗?
答案 0 :(得分:4)
我不确定这里的问题是什么,但是也有documentation page和various examples来了解如何使用hyperHTML,这与您使用它的方式并不完全相同。 / p>
实际上,由于hyperHTML是声明性的,因此不需要在其中引用任何内容,所以您宁愿这样写:
function update(text) {
var render = hyperHTML.bind(document.body);
render`static1 - <div>${text}</div> - static2`;
}
并在需要时致电update("any text")
。
这就是我的想法……这是正确的吗?
不,不是。 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永远不会删除注释,它将注释用作引脚,然后在需要更新任何内容时使用domdiff最终更新与这些引脚相关的节点。
Domdiff是petit-dom算法的无vDOM实现,而反过来又基于EW Myers的“ O(ND)差分算法及其变体” paper
每当漏洞中包含DOM节点时,hyperHTML就会理解这一点,并用这些节点填充这些漏洞。如果您重复传递相同的节点,hyperHTML将不会做任何事情,因为它充满了算法和明智的决定,所有这些都在文档中进行了描述,以便从其抽象中获得最佳性能。
所有这些东西以及更多的东西,对于任何浏览器都已标准化,一旦缩小并压缩,hyperHTML的权重约为7K,它还提供了以下功能:
作为总结,如果您需要这些简化操作并且不想重新发明轮子,我建议您尝试一下。
如果您只是想了解其工作原理,则无需承担任何责任,因为该项目是完全开源的。
到目前为止,我从您的问题中读到的所有内容都是,您只是相信了解它是如何工作的,因此希望在此答复中,我整理了您需要完全理解的所有遗漏之处。
您要编写自己的lit / hyperHTML库吗?继续,也可以随意使用domtagger或domdiff库,很少其他人已经在做同样的事情。