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

时间:2018-10-09 00:36:56

标签: hyperhtml

假设我有以下内容:

<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创建一个新元素,然后完全替换现有元素,但是那样我将无法继续绑定和仅更新已更改的内容。

1 个答案:

答案 0 :(得分:0)

这里很少有误解,我将尽力解决所有误解。

  

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

hyperHTML不是innerHMTL

人们看到模板文字,他们本能地认为它是innerHTML,但是hyperHTML就是innerHTML以外的所有内容。

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

两者之间的区别:

  1. innerHTML每次都浪费每个节点并从头开始创建所有内容,而hyperHTML始终将可见节点与特定上下文相关联
  2. innerHTML始终需要注入父元素,hyperHTML具有wire,这也是您要查找的内容,但我将在后面解释
  3. innerHTML可让您定义损坏的布局,hyperHTML会在您做错了某些事情并期望使用特定的语义(即没有部分属性的恶作剧)时抛出该错误

很抱歉,如果您已经知道这一点,但是我认为必须阐明hyperHTML背后的根本概念。

现在,让我们继续:-)

  

是否可以直接绑定到要修改的元素而不是其父元素?

是的,the wire

  

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

不。 Wires have 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'
});

您可以在code pen中实时测试以上代码。