Javascript 如何在内容更改后将hyperHTML重新呈现给同一元素

Javascript 如何在内容更改后将hyperHTML重新呈现给同一元素,javascript,rendering,hyperhtml,Javascript,Rendering,Hyperhtml,我试着支持和你一样的东西 我的代码看起来像 const elem = document.getElementById("profile") const render = hyperHTML.bind(elem); const name = elem.textContent render`<b>Hi ${name}</b>` const elem=document.getElementById(“概要文件”) const render=hyperHTML.bind(ele

我试着支持和你一样的东西

我的代码看起来像

const elem = document.getElementById("profile")
const render = hyperHTML.bind(elem);
const name = elem.textContent
render`<b>Hi ${name}</b>`
const elem=document.getElementById(“概要文件”)
const render=hyperHTML.bind(elem);
const name=elem.textContent
render`Hi${name}`
所以API看起来像

<div id="profile">alax</div> I will try to answer as best as I can, but I'll start saying that when asking for help, it'd be much easier/better to show the simplest use case you are trying to solve.

There is a lot of "surrounding" code in your fiddles so that I'll try to answer only to
hyperHTML
related bits.


hyper-element ?

I am not sure what's the goal of the library but
hyperHTML
exposes
hyper.Component
, and there's also an official HyperHTMLElement class to extend, which does most of the things you manually implement in your examples.

I'll keep answering your questions but please consider trying, at least, the official alternative and maybe push some change there if needed.


partial templates

hyperHTML pattern and strength is the Template Literal standard. Accordingly, to generate TL from the DOM would require either parsing of the content or code evaluation. Both solutions aren't the way to go.

Custom Elements require JavaScript to work, and without JS your partial template is useless and also potentially confusing for the user/consumer.

You don't want to define what to do with the
data
in the layout, you want to define a Custom Element behavior within the class that defines it.

That means: get rid of old-style in-DOM output, and simply use the Custom Element class to define its content. You maintain the related class only instead of maintaining a layout that has no knowledge about how the CE should represent that data.

TL;DR the following is a bad hyperHTML pattern:

<user-list data="[{name:'ann',url:''},{name:'bob',url:''}]">
  <div><a href="{#url}">{#name}</a></div>
</user-list>

alax我会尽可能地回答,但我会开始说,在寻求帮助时,展示您试图解决的最简单用例会更容易/更好

您的小提琴中有很多“环绕”的代码,因此我将尝试只回答
hyperHTML
相关位


超元素?

我不确定这个库的目标是什么,但是
hyperHTML
公开了
hyper.Component
,还有一个官方的扩展,它完成了您在示例中手动实现的大部分事情

我会继续回答你的问题,但请考虑尝试,至少是官方的替代方案,如果需要的话,也许会提出一些改变。
部分模板

hyperHTML模式和强度是模板文字标准。因此,从DOM生成TL需要对内容进行解析或代码求值。这两种解决方案都不可取

自定义元素需要JavaScript才能工作,如果没有JS,您的部分模板将毫无用处,并且可能会让用户/消费者感到困惑

您不想定义如何处理布局中的
数据
,而是想在定义该数据的类中定义自定义元素行为

这意味着:摆脱DOM输出中的旧样式,只需使用自定义元素类来定义其内容。您只维护相关类,而不是维护一个不知道CE应该如何表示该数据的布局

TL;DR以下是错误的超HTML模式:

<user-list data="[{name:'ann',url:''},{name:'bob',url:''}]"></user-list>
上面的代码片段不同于将JSON作为数据属性文本,因此您的示例应该使用
数据JSON
名称,并且类应该记住在其构造函数中使用
JSON.parse(this.dataset.JSON)
(或者使用一个属性观察器为您这样做)


hyperHTML拥有元素

当你写作时:

看起来hyperHTML将子元素的内容设置在元素前面,并在不设置内容的情况下创建元素

您假设您应该关心
hyperHTML
所做的事情:您不应该

您唯一应该了解的是
hyperHTML
拥有它所处理的节点。如果您通过不同的库或手动丢弃这些节点,则说明您做错了

hyperHTML(document.body)`<p>${'a'} b ${'c'}</p>`
a
c
都将有一个注释作为锚节点,以便以后能够用任何内容更新其内容

hyper(document.body)`${['text']}`;
// you can clean up the text through empty array
hyper(document.body)`${[]}`;
// re-populate it with new content
hyper(document.body)`${['a', 'b', 'c']}`;
上面的示例仍然比更改模板好,因为所有内容的优化都已经存在

但是,如果要确保节点是通过
hyperHTML
创建的初始节点,假设没有第三方脚本对该节点进行变异/垃圾处理,则可以使用连接

const body=hyper()`my${'content'}

`; document.body.textContent=''; document.body.appendChild(body);
这有点极端,但至少更快


作为摘要

看起来您正试图潜入一个应用程序,该应用程序一直通过不同的第三方库破坏布局

除非您创建一个封闭的阴影DOM引用,并在布局中删除部分模板,否则您总是会遇到基于DOM内容副作用的库问题,这些库会改变它们不拥有的元素

hyperHTML
中,所有权概念是关键,就像在
React
中一样,您不能在运行时更改为组件定义的JSX,您不应该尝试在运行时更改为
hyperHTML
定义的模板文本


现在,尽管我很想解决你的所有问题,但我觉得问你一个问题是对的:你确定
hyperHTML
真的是你当前应用的解决方案吗?如果您不使用封闭模式Shadow DOM和
hyperHTML
来更新您的DOM,那么第三方库引起的周围副作用似乎会不断打破您的预期。

当您说“内容已更改”(哪些内容?)时,您正在做什么或您指的是什么是非常不清楚的您使用的是
innerHtml
,我不确定是什么/为什么/在哪里。如果你能写一个代码笔或一个合适的例子(你能写的最简单的),我很乐意帮忙。如果在其他地方更改配置文件而不使用渲染,则会绕过hyperHTML。如果您通过hyperHTML编辑/更新内容,请确保始终通过hyperHTML进行编辑/更新。如果您干扰了外部的、未知的、未跟踪的突变,对于hyperHTML,您就做错了。记住,hyperHTML中没有虚拟DOM,您定义的DOM本身就是您处理的结构。谢谢您的帮助。1) React中经常使用“部分模板”模式。所以我只是想在这里做同样的事情。2) 您的示例显示了简单元素(“p”标记),但我的观点是,在尝试将内容插入自定义元素时,hyperHTML会中断。自定义web组件(无论是什么)在由hyperHTML创建时都不会传递内容。这就是为什么父元素(在Dom源代码中定义)和由hyperHTML创建的类似元素没有:(我以前使用过Shadow Dom,但firefoxOn“强制拥有内容”中不支持它)在我的例子中,99%的重新渲染来自元素内部,因此hyperHTML缓存很好,在1%上,我不介意重建元素..如果这是唯一的选择。但这又回到了原来的问题。如果你能向我展示你正在尝试做的最基本的例子,我可能会给出
hyperHTML(document.body)`<p>${'a'} b ${'c'}</p>`
hyperHTML(document.body)`<p>${[list, of, nodes]} b ${otherThing}</p>`
hyper(document.body)`${['text']}`;
// you can clean up the text through empty array
hyper(document.body)`${[]}`;
// re-populate it with new content
hyper(document.body)`${['a', 'b', 'c']}`;
const body = hyper()`<p>my ${'content'}</p>`;
document.body.textContent = '';
document.body.appendChild(body);