使用 hyperHTML,有没有办法直接绑定到要修改的元素而不是其父元素?
Using hyperHTML, is there a way to bind directly to an element to be modified rather than its parent?
假设我有以下内容:
<div id="parent">
<div id="child-one"><p>Child One</p></div>
<div id="child-two"><p>Child Two</p></div>
<div id="child-three"><p>Child Three</p></div>
</div>
据我了解,hyperHTML 设置您绑定到的元素的 innerHTML。如果我不仅要更改 #child-two 的 innerHTML,还要更改其属性而不触及 #child-one 和 #child-three,使用 hyperHTML 实现此目的的最佳方法是什么?
有没有办法直接绑定到要修改的元素而不是其父元素?
我知道我可以使用 wire 创建一个新元素,然后完全替换现有元素,但那样我就无法继续绑定并只更新已更改的元素。
这里有一些误解,我会尝试解决所有这些问题。
As I understand it, hyperHTML sets the innerHTML ...
hyperHTML 不是 innerHTML
人们看到模板字面量,他们本能地认为它是 innerHTML
,但 hyperHTML
是除了 innerHTML
.
之外的一切
名称是故意相似的,但实现与字符串无关,字符串只是用于映射 "all the things" 并将逻辑粘合在一起的声明外观。
两者的区别:
innerHTML
每次都会丢弃每个节点并从头开始创建所有内容,而 hyperHTML
relate always see nodes to a specific context
innerHTML
总是需要注入一个父元素,hyperHTML
有 wire
这也是你要找的,但我稍后会解释这个
innerHTML
允许您定义损坏的布局,hyperHTML
如果您做错了什么并期待特定的语义(即没有部分属性恶作剧), 将会抛出
抱歉,如果您已经知道这一点,但我认为有必要澄清 hyperHTML
背后的根本概念。
现在,让我们继续:-)
Is there a way to bind directly to an element to be modified rather than its parent?
是的,the wire。
I know I could use wire to create a new element and then completely replace the existing element, but then I would not have the ability to continue to bind and update only what has changed.
没有。 Wires have ids,因此每个 ID 将始终 return 完全相同的节点。
如果你想将 #child-two
连接到它的父级,但你也可以全局关联它,如果需要,你可以简单地通过一个 id 连接它。
const {bind, wire} = hyperHTML;
const outer = bind(document.body);
const inner = wire(document.body, ':child-two');
// you could wire inline but if you want
// to reuse the same node anywhere
// you need a callback to be sure the template literal
// is unique and not a different one each time (latest ES specs)
const child2 = model => inner`
<div id="child-two" onclick=${model.onclick}>
<p>${model.text}</p>
</div>`;
// you can update the parent node every time you want
const update = model => {
outer`
<div id="parent" onclick=${model.onclick}>
<div id="child-one"><p>Child One</p></div>
${
// and pass along any DOM node or wire you want
child2(model)
}
<div id="child-three"><p>Child Three</p></div>
</div>`;
};
update({
onclick(event) {
// will log "parent" or "child-two"
event.stopPropagation();
console.log(event.currentTarget.id);
},
text: 'This is Child 2'
});
您可以在 code pen.
中实时测试以上代码
假设我有以下内容:
<div id="parent">
<div id="child-one"><p>Child One</p></div>
<div id="child-two"><p>Child Two</p></div>
<div id="child-three"><p>Child Three</p></div>
</div>
据我了解,hyperHTML 设置您绑定到的元素的 innerHTML。如果我不仅要更改 #child-two 的 innerHTML,还要更改其属性而不触及 #child-one 和 #child-three,使用 hyperHTML 实现此目的的最佳方法是什么?
有没有办法直接绑定到要修改的元素而不是其父元素?
我知道我可以使用 wire 创建一个新元素,然后完全替换现有元素,但那样我就无法继续绑定并只更新已更改的元素。
这里有一些误解,我会尝试解决所有这些问题。
As I understand it, hyperHTML sets the innerHTML ...
hyperHTML 不是 innerHTML
人们看到模板字面量,他们本能地认为它是 innerHTML
,但 hyperHTML
是除了 innerHTML
.
名称是故意相似的,但实现与字符串无关,字符串只是用于映射 "all the things" 并将逻辑粘合在一起的声明外观。
两者的区别:
innerHTML
每次都会丢弃每个节点并从头开始创建所有内容,而hyperHTML
relate always see nodes to a specific contextinnerHTML
总是需要注入一个父元素,hyperHTML
有wire
这也是你要找的,但我稍后会解释这个innerHTML
允许您定义损坏的布局,hyperHTML
如果您做错了什么并期待特定的语义(即没有部分属性恶作剧), 将会抛出
抱歉,如果您已经知道这一点,但我认为有必要澄清 hyperHTML
背后的根本概念。
现在,让我们继续:-)
Is there a way to bind directly to an element to be modified rather than its parent?
是的,the wire。
I know I could use wire to create a new element and then completely replace the existing element, but then I would not have the ability to continue to bind and update only what has changed.
没有。 Wires have ids,因此每个 ID 将始终 return 完全相同的节点。
如果你想将 #child-two
连接到它的父级,但你也可以全局关联它,如果需要,你可以简单地通过一个 id 连接它。
const {bind, wire} = hyperHTML;
const outer = bind(document.body);
const inner = wire(document.body, ':child-two');
// you could wire inline but if you want
// to reuse the same node anywhere
// you need a callback to be sure the template literal
// is unique and not a different one each time (latest ES specs)
const child2 = model => inner`
<div id="child-two" onclick=${model.onclick}>
<p>${model.text}</p>
</div>`;
// you can update the parent node every time you want
const update = model => {
outer`
<div id="parent" onclick=${model.onclick}>
<div id="child-one"><p>Child One</p></div>
${
// and pass along any DOM node or wire you want
child2(model)
}
<div id="child-three"><p>Child Three</p></div>
</div>`;
};
update({
onclick(event) {
// will log "parent" or "child-two"
event.stopPropagation();
console.log(event.currentTarget.id);
},
text: 'This is Child 2'
});
您可以在 code pen.
中实时测试以上代码