function createElement(type, config, children) {
// 1. 创建一个对象
// 2.根据参数config修改这个对象
// 3.把children参数作为对象中props中的一个属性
let virtureDOM = {};
virtureDOM.type = type;
virtureDOM.ref = config.ref || null;
virtureDOM.key = config.key || null; let props = {}; // 虚拟dom的props
for (const attr in config) { // 遍历config 把除去ref和key的属性值复制到props中
if (attr === 'key' || attr === 'ref') continue;
else props[attr] = config[attr];
} const childrenLength = arguments.length - 2;// create可以传多个参数 第三个开始被认为是children
if (childrenLength === 1) {
props.children = children; // 如果只有一个 那么children就是第三个参数
} else if (childrenLength > 1) {
let childArray = Array(childrenLength); // 如果不止一个,就存入childArray数组中
for (let i = 0; i < childrenLength; i++) {
childArray[i] = arguments[i + 2];
}
props.children = childArray;
} virtureDOM.props = props;
return virtureDOM;
} // 把创建的对象转为真实DOM元素最后插入到页面中
function render(virtureDOM, container, callback) {
let { type, props } = virtureDOM || {};
let realDom = document.createElement(type); for (let attr in props) {
if (!props.hasOwnProperty(attr)) break; // 如果不是私有属性 直接跳出 说明已经遍历到原型上了
if (!props[attr]) continue; // 如果这个attr没有有效值,那么继续找下一个
const val = props[attr];
// 处理classname变成class
if (attr === 'className') realDom.setAttribute('class', val); else if (attr === 'children') { // 处理children
if (typeof val === 'string') { // 如果只有一个字符串children 那么直接渲染text出来
let text = document.createTextNode(val);
realDom.appendChild(text);
}
else if (val instanceof Array) { // 如果children是数组, 那么就得遍历这个数组分情况再渲染
for (let i = 0; i < val.length; i++) {
if (typeof val[i] === 'string') {
let text = document.createTextNode(val[i]);
realDom.appendChild(text);
} else {
render(val[i], realDom);
}
}
}
else { // 如果children只有一个且不是数组也不是字符串 那么应该是createElement出来的虚拟dom。递归
render(val, realDom);
}
} else if (attr === 'style') { // 处理style属性
if (val === '') continue; // style 有可能值为空字符串
for (let sty in val) {
if (val.hasOwnProperty(sty)) realDom['style'][sty] = val[sty];
}
} else realDom.setAttribute(attr, val); // 基于setAttribute可以让设置的属性表现在html的结构上
}
container.appendChild(realDom);
callback && callback();
} const virtureDom2 = createElement('span',
{}, 'age is 18!'); const virtureDom = createElement('div',
{
id: 'box',
className: 'lp',
style: { color: 'red' },
key: 12,
ref: 'refs'
}, 'my name is LanPang ', virtureDom2); render(virtureDom, document.getElementById('root'), () => console.log('finish'));

最新文章

  1. .Net中的RealProxy实现AOP
  2. Javascript的this用法及jQuery中$this和$(this)的区别
  3. JQuery ajax 异步传一个数组到 .net后台
  4. 你好,欢迎来到我的博客,我是博主royalmice1
  5. maven中使用junit老是找不到包
  6. Oracle实例、用户、权限和角色
  7. BZOJ1812 [IOI2005]river
  8. Oracle 存储过程异常处理
  9. CoreOS Linux available in China
  10. 项目源码--Android即时通讯IM客户端
  11. 【Android Studio使用教程 7】AndroidStudio问题汇总
  12. [resource]Github上维护的一个机器学习相关的框架,库和工具列表
  13. Cinder-2 窗口的创建过程
  14. Android 6.0 闪光灯的使用
  15. 看漫画,学 Redux
  16. codeforces 653D. Delivery Bears 网络流
  17. 数值类型中JDk的编译期检查和编译期优化
  18. Dorado7与@ManyToMany的矛盾分析
  19. babel基本用法
  20. CDI Features(EL(SPEL),Decorator,Interceptor,Producer)

热门文章

  1. ol,li,ul,dl,dt,dd
  2. ASCII码排序(hdu2000)
  3. A == B ?(hdu2054)
  4. Word使用技巧——持续更新
  5. 前端内网穿透,localtunnel你值得拥有!
  6. Spring_配置Bean &amp; 属性配置细节
  7. MANIFEST.MF是个什么?
  8. windows文本转语音 通过java 调用python 生成exe可执行文件一条龙
  9. unix 密码破解,zip破解总结
  10. XXE漏洞学习1