0

假设我有以下内容:

<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 完成此操作的最佳方法是什么?

有没有办法直接绑定到要修改的元素而不是其父元素?

我知道我可以使用线创建一个新元素,然后完全替换现有元素,但是我将无法继续绑定和仅更新已更改的内容。

4

1 回答 1

0

这里几乎没有误解,我将尝试解决所有这些误解。

据我了解,hyperHTML 设置了 innerHTML ...

hyperHTML 不是 innerHMTL

人们看到模板文字,他们本能地认为它是innerHTML,但hyperHTML不是innerHTML.

名称是故意相似的,但实现与字符串无关,字符串只是用于映射“所有事物”并将逻辑粘合在一起的声明性外观。

两者的区别:

  1. innerHTML每次每个节点都丢弃并从头开始创建所有内容,同时hyperHTML始终将节点与特定上下文相关联
  2. innerHTML总是需要注入一个父元素,hyperHTMLwire也是你要找的,但我稍后会解释
  3. innerHTML让您定义损坏的布局,hyperHTML如果您做错了什么并期望特定的语义(即没有部分属性恶作剧),则会抛出

如果您已经知道这一点,我深表歉意,但我认为必须澄清背后的根本概念hyperHTML

现在,让我们继续:-)

有没有办法直接绑定到要修改的元素而不是其父元素?

的,电线

我知道我可以使用线创建一个新元素,然后完全替换现有元素,但是我将无法继续绑定和仅更新已更改的内容。

不,电线有 ids,因此每个 ID 将始终返回完全相同的节点。

如果你想连接#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'
});

您可以在代码笔中实时测试上述代码。

于 2018-10-25T04:19:20.737 回答