使用hyper.Component时访问DOM

时间:2017-09-11 23:10:48

标签: javascript hyperhtml

使用HyperHTMLElement时,只需使用this.childrenthis.querySelector()就可以访问该组件的内容,因为它是一个元素。

但是在使用hyper.Component时我将如何实现类似的行为?

我想到的假设示例来自React docs:https://facebook.github.io/react/docs/refs-and-the-dom.html - 我想将特定节点集中在我的DOM中。

我有一个codepen沙箱,我正试图解决这个问题:https://codepen.io/asapach/pen/oGvdBd?editors=0010

我的想法是render()每次都会返回相同的Node,因此我可以在返回之前保存它,稍后以this.node的形式访问它:

render() {
  this.node = this.html`
    <div>
      <input type="text" />
      <input type="button" value="Focus the text input" onclick=${this} />
    </div>
  `;
  return this.node;
}

但这对我来说并不干净。有更好的方法吗?

2 个答案:

答案 0 :(得分:2)

handleEvent模式可以帮助您。这种模式背后的想法是,当行为是事件驱动时,你永远不需要保留DOM引用,因为你总是可以通过event.currentTarget检索节点,总是指向附加了监听器的元素,或{{ 1}},适用于附加到wrap元素的通用单击处理程序中的其他位置发生的点击,在您的演示案例中为event.target

如果您想使用这些信息,可以使用属性来丰富您的组件以识别它们,就像根元素上的div一样,然后到达它以执行您需要的任何其他操作。

data-is="custom-text-input"

您可以在代码笔的分支中看到一个工作示例: https://codepen.io/WebReflection/pen/RLNyjy?editors=0010

作为替代方案,您可以渲染组件并解决其内容一次,如另一个分支所示: https://codepen.io/WebReflection/pen/LzEmgO?editors=0010

onclick(e) {
  var node = e.target.closest('[data-is=custom-text-input]');
  node.querySelector('[type=text]').focus();
}

在一天结束时,如果你没有使用自定义元素而只是基本的,良好的DOM节点,你可以随时初始化/渲染它们,你不需要等待任何升级机制。 / p>

这里的好处和希望是安全的,除非你明确地公开它,否则没有办法解决/改变/改变与DOM元素相关的实例。

我希望这些可能性回答了你的问题。

答案 1 :(得分:0)

这是我过去通过https://github.com/joshgillies/hypercomponent

所做的工作

实施实际上非常简单。

class ElementalComponent extends hyper.Component {
  constructor () {
    super()
    const _html = super.html
    this.html = (...args) => {
      this.node = _html.apply(this, args)
      return this.node
    }
  }
}

class HelloWorld extends ElementalComponent {
  render () {
    return this.html`<div>Hello World!</div>`
  }
}

这非常有效并与您的问题内联。但是,值得注意的是hyperHTML不仅可以呈现单个节点,还可以呈现多个节点。举个例子:

hyper`<div>Hello World!</div>` // returns a single DOM Node
hyper`<div>Hello</div> <div>World!</div>` // returns multiple DOM Nodes as an Array.

因此this.node中的ElementalComponent可以是DOM节点,也可以是基于渲染器正在执行的操作的数组。