用普通的旧JS动态渲染DOM元素有什么好方法?

EFH*_*EFH 5 html javascript dom

我面临的挑战是使用普通的旧Javascript构建单页应用程序,不允许使用任何库或框架.虽然在React和Angular中创建动态DOM元素相当简单,但我提出的vanilla JS解决方案看起来很笨拙.我想知道是否有一种特别简洁或有效的方法来构建动态呈现的DOM元素?

下面的函数接收一个从GET请求接收的数组,并为每个项呈现一个div,传入该值(就像在React和render子元素中映射结果一样).

 function loadResults(array) {
  array.forEach(videoObject => {
    let videoData =  videoObject.snippet;
    let video = {
       title : videoData.title,
       img : videoData.thumbnails.default.url,
       description : videoData.description
    };
    let div = document.createElement("DIV");
    let img = document.createElement("IMG");
    img.src = video.img;
    let h4 = document.createElement("h4");
    let title = document.createTextNode(video.title);
    h4.appendChild(title);
    let p = document.createElement("p");
    let desc = document.createTextNode(video.description);
    p.appendChild(desc);

    div.appendChild(img);
    div.appendChild(h4);
    div.appendChild(p);
    document.getElementById('results')
      .appendChild(div);
  });
}
Run Code Online (Sandbox Code Playgroud)

这感觉不必要地笨重,但我还没有找到一种更简单的方法来做到这一点.

提前致谢!

Mad*_*iha 9

注意:我在这里说的一切都是概念证明等级,仅此而已.它不处理错误或异常情况,也没有在生产中进行测试.请自行决定使用.

一个好的方法是创建一个为您创建元素的函数.像这样的东西:

const crEl = (tagName, attributes = {}, text) => {
  const el = document.createElement(tagName);
  Object.assign(el, attributes);
  if (text) { el.appendChild(document.createTextNode(text)); }

  return el;
};
Run Code Online (Sandbox Code Playgroud)

然后你可以像这样使用它:

results
  .map(item => crEl(div, whateverAttributes, item.text))
  .forEach(el => someParentElement.appendChild(el));
Run Code Online (Sandbox Code Playgroud)

我见过的另一个很酷的概念证明是使用ES6 Proxies作为一种模板引擎.

const t = new Proxy({}, {
  get(target, property, receiver) {
    return (children, attrs) => {
      const el = document.createElement(property);
      for (let attr in attrs) {
        el.setAttribute(attr, attrs[attr]);
      }
      for (let child of(Array.isArray(children) ? children : [children])) {
        el.appendChild(typeof child === "string" ? document.createTextNode(child) : child);
      }
      return el;
    }
  }
})

const el = t.div([
  t.span(
    ["Hello ", t.b("world!")], {
      style: "background: red;"
    }
  )
])

document.body.appendChild(el);
Run Code Online (Sandbox Code Playgroud)

代理捕获get目标对象(为空),并呈现具有被调用方法名称的元素.这会导致您看到非常酷的语法const el =.