我正在尝试支持与React.Children
相同类型的事情我的代码看起来像
const elem = document.getElementById("profile")
const render = hyperHTML.bind(elem);
const name = elem.textContent
render`<b>Hi ${name}</b>`
所以API看起来像
<div id="profile">alax</div> <div id="profile"><b>Hi alax</b></div>
我正在使用MutationObserver重新报道内容更改
但如果内容已更改。 hyperHTML表示它依赖于正确的元素..但元素保持其innerHtml(无更新)
我可以看到<!--_hyper: -2001947635;-->
已删除,然后设置了内容,但设置了渲染&amp; hyperHTML.bind 再次无效
任何想法都会很棒! THX
更新
上述问题的解决方法是调用hyperHTML.bind``
然后使用hyperHTML进行正常渲染
上下文 - 我使用hyperHTML创建自定义元素库(hyper-element)
我的用例:我在混合技术项目中工作(有些人使用jQuery)
旁注,关于原因。我想支持像部分模板
这样的东西部分模板的示例:
<user-list data="[{name:'ann',url:''},{name:'bob',url:''}]">
<div><a href="{#url}">{#name}</a></div>
</user-list>
输出:
<user-list data="[{name:'ann',url:''},{name:'bob',url:''}]">
<div><a href="">ann</a></div>
<div><a href="">bob</a></div>
</user-list>
这是在您控制的元素中设置自定义内容的一种用法
目前,我通过三方工作/重新审核来设置内容
https://jsfiddle.net/k25e6ufv/16/
我现在的问题是:它正在重新发送另一个自定义元素并将传递内容传递给子元素
看起来hyperHTML正在将元素前面的子元素内容设置为元素,并在不设置内容的情况下创建元素
向下滚动到源代码底部以查看实施情况!
https://jsfiddle.net/k25e6ufv/14/
撕毁疯猫:
Html`
xxx: ${this.wrapedContent} zzzz
`
当前输出:
wrapedContent: ppp time:11:35:48 ~ crazy-cats: **Party 11:35:48** xxx: zzzz
<crazy-cats>Party 11:37:21 xxx: <!--_hyper: -362006176;--> zzzz </crazy-cats>
期望的输出:
wrapedContent: ppp time:11:35:48 ~ crazy-cats: xxx: **Party 11:35:48** zzzz
<crazy-cats> xxx: Party 11:37:21 zzzz </crazy-cats>
答案 0 :(得分:1)
我会尽力回答,但我会开始说,在寻求帮助时,更容易/更好地展示您尝试解决的最简单的用例。
周围有很多&#34;&#34;您的小提琴中的代码,以便我尝试仅回答hyperHTML
相关位。
超元素?
我不确定图书馆的目标是什么,但hyperHTML
公开了hyper.Component
,还有一个官方HyperHTMLElement class要扩展,这大多数都是您在示例中手动实现的内容。
我会继续回答您的问题,但请考虑尝试,至少是官方替代方案,如果需要可能会推动一些改变。
部分模板
hyperHTML 模式和强度是Template Literal标准。因此,要从DOM生成TL,需要解析内容或代码评估。这两种解决方案都没有办法。
自定义元素需要JavaScript才能工作,如果没有JS,您的部分模板将毫无用处,并且可能会让用户/消费者感到困惑。
您不想定义如何处理布局中的data
,您希望在定义它的类中定义自定义元素行为。
这意味着:摆脱旧式的DOM内输出,只需使用Custom Element类来定义其内容。您只维护相关类,而不是维护一个不知道CE应如何表示该数据的布局。
TL; DR 以下是一个糟糕的hyperHTML模式:
<user-list data="[{name:'ann',url:''},{name:'bob',url:''}]">
<div><a href="{#url}">{#name}</a></div>
</user-list>
你要做的就是写下这个:
<user-list data="[{name:'ann',url:''},{name:'bob',url:''}]"></user-list>
但是小心,data
中的hyperHTML
属性仅在通过模板文字传递时才是特殊的。如果要将JSON传递给组件,请以不同方式调用该属性。
// hyperHTML data is special, no need to use JSON
render`<c-e data=${{as: 'it is'}}></c-e>`
上面的代码段不同于将JSON作为数据属性文本,因此您的示例应使用data-json
名称,并且该类应记住其构造函数中的JSON.parse(this.dataset.json)
(或者具有执行此操作的属性观察者你)
hyperHTML拥有元素
当你写:
看起来hyperHTML正在将元素的前面内容设置为元素,并在不设置内容的情况下创建元素
你认为你应该关心hyperHTML
所做的事情:你不应该这样做。
您唯一应该理解的是hyperHTML
拥有它处理的节点。如果您通过不同的库或手动删除这些节点,那么您做错了。
hyperHTML(document.body)`<p>hello ${'world'}</p>`;
// obtrusive libraries ... later on ...
document.body.textContent = 'bye bye';
// hyperHTML still owns the body content
hyperHTML(document.body)`<p>hello ${'world'}</p>`;
上面的片段完全没问题,完全错了。
您不会手动更新body
内容,也不会通过jQuery
或其他图书馆干扰其内容,您根本不应该删除内容。
一旦您选择hyperHTML
来处理绑定的上下文,那么您已经做出了选择。
这个世界上几乎每个图书馆都是如此。如果你使用Angular来创建一些东西而你通过jQuery搞得一团糟,那就会破坏。如果您编写主干模板,然后手动将其内容弄乱,那就会中断。
如果将一个元素绑定到hyperHTML
并将其与其他库混淆,则会中断。
唯一不会破坏的是电线,这意味着你创建电线的那一刻,你可以直接附加它,它实际上是一个DOM节点,所以它会在那里,它将被处理hyperHTML
。
然而,您应该使用hyperHTML
来处理这些更改,而不是jQuery或JS本身。
输出正确
当你说输出不应该包含评论时,你假设你应该关心通过hyperHTML
产生什么输出:你不应该!
hyperHTML
使用注释作为分隔符,这些对于性能,不受重绘和重排以及部分更改(如下所示)都非常好:
hyperHTML(document.body)`<p>${'a'} b ${'c'}</p>`
a
和c
都会将评论作为主播节点,以便稍后可以使用任何内容更新其内容。
hyperHTML(document.body)`<p>${[list, of, nodes]} b ${otherThing}</p>`
你改变插值?好的,hyperHTML
知道要替换什么以及在哪里。
强制拥有内容
如果您使用其他模板文字来重新填充绑定节点,则会破坏缓存并创建新内容。
此时您最好使用innerHTML
,因为hyperHTML
的所有功能都将消失。
首先,如果您的内容变化太大,请使用数组。
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()`<p>my ${'content'}</p>`;
document.body.textContent = '';
document.body.appendChild(body);
它有点极端,但至少更快。
作为摘要
看起来你正试图将hyperHTML
潜入一个应用程序,该应用程序一直通过不同的第三方库来破坏布局。
除非你创建一个封闭的Shadow DOM引用并且你通过布局删除部分模板,否则你总是会遇到基于DOM内容副作用的库问题,这些库会改变他们不拥有的元素。< / p>
在hyperHTML
中,所有权概念是关键,就像在React
中你无法在运行时更改组件的已定义JSX时,你永远不应该尝试在运行时更改{{1的定义模板文字}}
现在,尽管我想解决您的所有问题,但我觉得问您是对的:您确定hyperHTML
是否真的是您当前应用的解决方案?如果您不使用封闭模式Shadow DOM和hyperHTML
仅来更新您的DOM,那么由第三方库引起的周围副作用看起来会不断打破您的期望。