Git Product home page Git Product logo

Comments (14)

Sunny-117 avatar Sunny-117 commented on July 16, 2024 3
// 真正的渲染函数
function _render(vnode) {
  // 如果是数字类型转化为字符串
  if (typeof vnode === "number") {
    vnode = String(vnode);
  }
  // 字符串类型直接就是文本节点
  if (typeof vnode === "string") {
    return document.createTextNode(vnode);
  }
  // 普通DOM
  const dom = document.createElement(vnode.tag);
  if (vnode.attrs) {
    // 遍历属性
    Object.keys(vnode.attrs).forEach((key) => {
      const value = vnode.attrs[key];
      dom.setAttribute(key, value);
    });
  }
  // 子数组进行递归操作
  vnode.children.forEach((child) => dom.appendChild(_render(child)));
  return dom;
}

from js-challenges.

lxy-Jason avatar lxy-Jason commented on July 16, 2024 1

仅完成题目要求版本,可以直接F12查元素看结果

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <script>
    function render(vnode) {
      const { tag, attrs = {}, children } = vnode;
      //创建dom
      let el = document.createElement(tag);
      //添加attr
      for (const key in attrs) {
        el.setAttribute(key, attrs[key]);
      }
      //处理children
      if (Array.isArray(children) && children.length > 0) {
        children.forEach(child => el.appendChild(render(child)));//子元素添加在父元素中
      }
      return el
    }
    const vnode = {
      tag: 'DIV',
      attrs: {
        id: 'app'
      },
      children: [
        {
          tag: 'SPAN',
          children: [
            { tag: 'A', children: [] }
          ]
        },
        {
          tag: 'SPAN',
          children: [
            { tag: 'A', children: [] },
            { tag: 'A', children: [] }
          ]
        }
      ]
    }
    document.body.appendChild(render(vnode))
  </script>
</body>
</html>

from js-challenges.

Leadgq avatar Leadgq commented on July 16, 2024 1

function _render(vNode) {
// 解构
const {tag, attrs, children} = vNode;
const root = document.createElement(tag.toLowerCase());
for (const key in attrs) {
root.setAttribute(key, attrs[key])
}
// 字符串
if (typeof children === 'string') {
root.appendChild(document.createTextNode(children));
// 数组
} else if (Array.isArray(children) && children.length > 0) {
// 递归添加
children.forEach(item => root.appendChild(_render(item)))
}
return root
}

from js-challenges.

Bbbtt04 avatar Bbbtt04 commented on July 16, 2024 1
function render(vnode) {
  if (typeof vnode === 'number') {
    vnode = String(vnode)
  }

  if (typeof vnode === 'string') {
    return document.createTextNode(vnode)
  }

  let dom = document.createElement(vnode.tag)
  if (vnode.attrs) {
    Object.keys(vnode.attrs).map(key => {
      let value = vnode.attrs[key]
      dom.setAttribute(key, value)
    })
  }
  vnode.children && vnode.children.map(item => {
    dom.appendChild(render(item))
  })
  return dom
}

from js-challenges.

truejiang avatar truejiang commented on July 16, 2024
function render(vnode) {

  const { tag, attrs = {}, children } = vnode

  // 开始通过vnode去创建dom
  const el = document.createElement(String(tag).toLocaleLowerCase())

  // 处理 attrs
  for (const key in attrs) {
    el.setAttribute(key, attrs[key])
  }


  // 处理children
  if(typeof children === 'string') {
    // 如果children是字符串,当做文本文本节点插入
    el.appendChild(document.createTextNode(children))
  } else if(Array.isArray(children) && children.length > 0) {
    // 如果是数组需要递归的render
    children.forEach(child => render(child, el))
  }

  return el
}

from js-challenges.

lxy-Jason avatar lxy-Jason commented on July 16, 2024
function render(vnode) {

  const { tag, attrs = {}, children } = vnode

  // 开始通过vnode去创建dom
  const el = document.createElement(String(tag).toLocaleLowerCase())

  // 处理 attrs
  for (const key in attrs) {
    el.setAttribute(key, attrs[key])
  }


  // 处理children
  if(typeof children === 'string') {
    // 如果children是字符串,当做文本文本节点插入
    el.appendChild(document.createTextNode(children))
  } else if(Array.isArray(children) && children.length > 0) {
    // 如果是数组需要递归的render
    children.forEach(child => render(child, el))
  }

  return el
}

你忘记把子元素要添加到父元素中了吧?

from js-challenges.

yang-xianzhu avatar yang-xianzhu commented on July 16, 2024
   function renderer(vnode) {
      const el = document.createElement(vnode.tag.toLocaleLowerCase());

      // 处理attrs
      for (const k in vnode.attrs) {
        el.setAttribute(k, vnode.attrs[k]);
      }
      //  如果children是字符串
      if (typeof vnode.children === "string") {
        const textNode = document.createTextNode(vnode.children);
        el.appendChild(textNode);
      }
      // 如果chidlren是数组,并且不是空数组时,就递归转化
      if (Array.isArray(vnode.children) && vnode.children.length > 0) {
        vnode.children.forEach((child) => {
          el.appendChild(renderer(child, el));
        });
      }
      return el;
    }

from js-challenges.

veneno-o avatar veneno-o commented on July 16, 2024
function _render(vnode) {
  // 考虑非一般性, 临界值
	if (typeof vnode === "number") {
		vnode = String(vnode);
	}
	if (typeof vnode === "string") {
		return document.createTextNode(vnode);
	}
  // 不失一般性
	const dom = document.createElement(vnode.tag);
	if (vnode.attrs) {
		for (const key in vnode.attrs) {
			dom.setAttribute(key, vnode.attrs[key]);
		}
	}
	if (vnode.children) {
		vnode.children.forEach((newVnode) => {
			dom.appendChild(_render(newVnode));
		});
	}
	return dom;
}

from js-challenges.

sunshineLixun avatar sunshineLixun commented on July 16, 2024
/**
 * {
  tag: 'DIV',
  attrs:{
  id:'app'
  },
  children: [
    {
      tag: 'SPAN',
      children: [
        { tag: 'A', children: [] }
      ]
    },
    {
      tag: 'SPAN',
      children: [
        { tag: 'A', children: [] },
        { tag: 'A', children: [] }
      ]
    }
  ]
}
把上诉虚拟Dom转化成下方真实Dom
<div id="app">
  <span>
    <a></a>
  </span>
  <span>
    <a></a>
    <a></a>
  </span>
</div>
 */

function render(vnode) {
  if (typeof vnode === "string") {
    return document.createTextNode(vnode);
  }
  if (typeof vnode === "number") {
    vnode = String(vnode);
  }
  let dom = document.createElement(vnode.tag);
  if (vnode.attrs) {
    for (const key in vnode.attrs) {
      dom.setAttribute(key, vnode.attrs[key]);
    }
  }

  if (vnode.children) {
    if (typeof vnode.children === "object") {
      vnode.children.forEach((child) => {
        dom.appendChild(render(child));
      });
    } else if (
      typeof vnode.children === "string" ||
      typeof vnode.children === "number"
    ) {
      if (typeof vnode.children === "number") {
        vnode.children = String(vnode.children);
      }
      dom.appendChild(document.createTextNode(vnode.children));
    }
  }

  return dom;
}

function test() {
  const vnode = {
    tag: "DIV",
    attrs: {
      id: "app",
    },
    children: [
      {
        tag: "SPAN",
        children: [
          {
            tag: "A",
            children: [{ tag: "P", attrs: { text: "p" }, children: 123213 }],
          },
        ],
      },
      {
        tag: "SPAN",
        children: [
          { tag: "A", children: [] },
          { tag: "A", children: [] },
        ],
      },
    ],
  };

  const dom = render(vnode);
  console.log(dom);
}

test();

from js-challenges.

whale2002 avatar whale2002 commented on July 16, 2024

题目要求,这里增加了具体的节点内容,便于理解。

把上诉虚拟Dom转化成下方真实Dom
<div id="app">
  <span>
    <a></a>
  </span>
  <span>
    <a>123</a>
    <a>456</a>
    789
  </span>
</div>

实现

const vDom = {
    tag: 'DIV',
    attrs: {
        id: 'app'
    },
    children: [
        {
            tag: 'SPAN',
            children: [{tag: 'A', children: []}]
        },
        {
            tag: 'SPAN',
            children: [
                {tag: 'A', children: [123]},
                {tag: 'A', children: [456]},
                789
            ]
        }
    ]
};

function render(vNode) {
    // 递归终止条件
    if (typeof vNode === 'number')
        return document.createTextNode(String(vNode));
    if (typeof vNode === 'string') return document.createTextNode(vNode);

    const {tag, attrs = {}, children = []} = vNode;
    const dom = document.createElement(tag);

    Object.keys(attrs).forEach((attr) => {
        dom.setAttribute(attr, attrs[attr]);
    });

    children.forEach((child) => {
        dom.append(render(child));
    });

    return dom;
}

const dom = render(vDom);

from js-challenges.

xun-zi avatar xun-zi commented on July 16, 2024
function render(data) {
        const curNode = document.createElement(data.tag);
        for (let key in curNode.attrs) {
            curNode.setAttribute(key, curNode.attrs[key]);
        }
        for (let child of data.children) {
            curNode.append(render(child));
        }
        return curNode;
    }

from js-challenges.

ashwat07 avatar ashwat07 commented on July 16, 2024
const renderDom = function (jsonDom) {
  const mainEl = document.createElement(jsonDom?.tag?.toLowerCase());

  if (jsonDom.attrs) {
    Object.keys(jsonDom.attrs).forEach((attr) => {
      mainEl.setAttribute(attr, jsonDom.attrs[attr]);
    });
  }
  jsonDom.children.forEach((child) => {
    mainEl.appendChild(renderDom(child));
  });
  return mainEl;
};

from js-challenges.

Simonduya avatar Simonduya commented on July 16, 2024
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <script>
      const jump = () => {
        alert(666);
      };
      const vnode = {
        tags: "div",
        props: {
          id: "box",
          style: "width:100px; color:red",
        },
        children: [
          {
            tags: "a",
            props: {
              onClick: jump,
            },
            children: "hahaha",
          },
        ],
      };
      const render = (vnode) => {
        const { tags, props, children } = vnode;
        const el = document.createElement(tags);

        if (props) {
          for (const key in props) {
            const value = props[key];
            if (key.startsWith("on")) {
              el.addEventListener(key.slice(2).toLowerCase(), value);
            } else {
              el.setAttribute(key, value);
            }
          }
        }
        console.log(children);
        if (children) {
          if (typeof children === "string") {
            el.textContent = children;
          } else {
            children.forEach((item) => {
              el.appendChild(render(item));
            });
          }
        }

        return el;
      };
      document.body.appendChild(render(vnode));
    </script>
  </body>
</html>

就是mount的一些步骤

from js-challenges.

why-ztc avatar why-ztc commented on July 16, 2024
const render = (root) => {
  const dfs = (vdom) => {
    const { tag, attrs, children } = vdom
    if (!vdom) {
      return
    }
    const dom = document.createElement(tag)
    if (attrs) {
      Object.keys(attrs).forEach(key => {
        dom.setAttribute(key, attrs[key])
      })
    }
    if (Array.isArray(children) && children.length) {
      children.forEach(item => {
        dom.appendChild(dfs(item))
      })
    }
    return dom
  }
  const res = dfs(root)
  return res
}

from js-challenges.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.