首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >呈现到文档中嵌套的dom节点

呈现到文档中嵌套的dom节点
EN

Stack Overflow用户
提问于 2020-05-12 06:23:29
回答 1查看 63关注 0票数 0

我在玩弄如何将html渲染到文档中,主要是为了好玩和学习。我看到了react以及大多数vdom/hyperscript实现是如何递归呈现嵌套节点的。我想知道如何用数组实现类似的东西。

因此,如果我有一个函数返回一个render方法,那么它将输出一个数组。

代码语言:javascript
复制
    function Comp() {
        return {
          render: function () {
            return [
              "<div>",
              '  <button name="button-test" type="button">test</button>',
              SubComp(),
              "</div>",
            ];
          },
          postRender: function (dom) {
            dom
              .querySelector("button[name=button-test]")
              .addEventListener("click", function () {
                console.log("haha");
              });
          },
        };
      }


      function SubComp() {
    return {
      render: function () {
        return [
          "<div>",
          '  <button name="button-does-nothing" type="button">nothing</button>',
          "</div>",
        ];
      },
    };
  }

在上面的示例中,我可以忽略postrender方法,从Comp内部调用SubComp().render()方法并执行以下操作:

代码语言:javascript
复制
 document.getElementById('someid').innerHTML(Comp().render().flat(Infinity).join(''));

然后执行任何与dom相关的事情。它会嵌套我扔进去的任何东西。但我也失去了在每个函数上工作的能力,例如,如果我想要为html的该节点或部分附加dom事件。

所以我的问题是,有没有人知道我如何通过为每个函数提供dom节点来实现这一点。然后,我可以执行它的postrender方法(或者当节点准备好时我想使用的wtv ),然后将它嵌套到它可能拥有的外部节点中。

同样,这更像是一次练习和学习,所以请尽量不要向我建议库或框架。

PS:在运行时将返回的数组转换为hyperscript对象也适用于我,如果有人知道怎么做的话。

非常感谢。

EN

回答 1

Stack Overflow用户

发布于 2020-05-14 02:55:46

这就是我想出来的。

我认为这可以通过reduce来改进。这就是我目前所走的路程,没有做太多的测试,但它似乎起作用了。

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
  <head>
    <script>
    function render(component) {
  if (component.preRender) {
    component.preRender();
  }
  var thisComponent = component.render();
  var thisDom = document.createElement('div');
  var children = [];
  thisComponent.forEach(function (c, index) {
    if (typeof c === 'object' && c.hasOwnProperty('render')) {
      children.push(render(c, thisDom.querySelector('div')));
      thisComponent[index] = '<div id="child' + (children.length) + '"></div>';
    }
  });
  var parsedDom = new DOMParser().parseFromString(thisComponent.flat(Infinity).join(''), 'text/html').body.childNodes;
  var length = parsedDom.length;
  for (var i = 0; i < length; i += 1) {
    thisDom.appendChild(parsedDom[0]);
  }
  if (component.postRender) {
    component.postRender(thisDom);
  }
  children.forEach(function (child, index) {
    while (child.firstChild) {
      var tchild = child.removeChild(child.firstChild);
      thisDom.querySelector('[id=child' + (index + 1) + ']').parentElement.insertBefore(tchild, thisDom.querySelector('[id=child' + (index + 1) + ']'));
    }
    thisDom.querySelector('[id=child' + (index + 1) + ']').remove();
  });
  return thisDom;
}
    </script>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <div id="app"></div>
  </body>
</html>
<script>
  function Component() {
    return {
      render: function () {
        return [
          '  <button name="button-test" type="button">test click me</button>',
          '<div id="test">',
          SubComponent(),
          "</div>",
        ];
      },
      postRender: function (dom) {
        dom
          .querySelector("button[name=button-test]")
          .addEventListener("click", function () {
            console.log("this was added while detached haha");
          });
      },
    };
  }
  function SubComponent() {
    return {
      render: function () {
        return [
          '  <button name="button-does-nothing" type="button">nothing</button>',
          SubSubComp(),
        ];
      },
    };
  }
  function SubSubComp() {
    return {
      render: function () {
        return [
          '  <button name="button-does-nothing-too" type="button">does nothing as well</button>',
        ];
      },
    };
  }
  document.getElementById("app").appendChild(render(Component()));
</script>

因此,如果有人可以帮助改进代码,我也会接受作为答案。

另外,你们知道操纵分离dom的速度有多快吗?或者,这方面有基准吗?我只找到了连接到浏览器的dom。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61740441

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档