首先我们可以看到,在 createElement 函数挪用的处所,我们的文本被当成字符串传入,然后这个参数是吸收子节点的,而且在我们的逻辑之中我们利用了 appendChild,这个函数是吸收 DOM 节点的。显然我们的文本字符串不是一个节点,自然就会报错。
通过这种调试方法我们可以顿时定位到,我们需要在那边添加逻辑去实现这个成果。这种方法也可以算是一种捷径吧。
所以接下来我们就回到 main.js,在我们挂上子节点之前,判定以下 child 的范例,假如它的范例是 “String” 字符串的话,就利用 createTextNode() 来建设一个文本节点,然后再挂載到父元素上。这样我们就完成了字符节点的处理惩罚了。
function createElement(type, attributes, ...children) { // 建设元素 let element = document.createElement(type); // 挂上属性 for (let name in attributes) { element.setAttribute(name, attributes[name]); } // 挂上所有子元素 for (let child of children) { if (typeof child === 'string') child = document.createTextNode(child); element.appendChild(child); } // 最后我们的 element 就是一个节点 // 所以我们可以直接返回 return element; } let a = <div>hello world</div>; document.body.appendChild(a);
我们用这个最新的代码 webpack 打包之后,就可以在欣赏器上看到我们的文字被显示出来了。
到了这里我们编写的 createElement 已经是一个较量有用的对象了,我们已经可以用它来做必然的 DOM 操纵。甚至它可以完全取代我们本身去写 document.createElement 的这种重复繁琐的操纵了。
这里我们可以验证以下,我们在 div 傍边从头加上我们之前的三个 span, 而且在每个 span 中插手文本。11
let a = ( <div> hello world: <span>a</span> <span>b</span> <span>c</span> </div> );
然后我们从头 webpack 打包后,就可以看到确实是可以完整这种 DOM 的操纵的。
此刻的代码已经可以完成必然的组件化的基本本领。
实现自界说标签之前我们都是在用一些,HTML 自带的标签。假如我们此刻把 div 中的 d 改为大写 D 会怎么样呢?
let a = ( <Div> hello world: <span>a</span> <span>b</span> <span>c</span> </Div> );
果不其然,就是会报错的。不外我们找到了问题来源的要害,这里我们发明当我们把 div 改为 Div 的时候,传入我们 createElement 的 div 从字符串 ‘div' 酿成了一个 Div 类。
虽然我们的 JavaScript 中并没有界说 Div 类,这里自然就会报 Div 未界说的错误。知道问题的地址,我们就可以去办理它,首先我们需要先办理未界说的问题,所以我们先成立一个 Div 的类。
// 在 createElment 函数之后插手 class Div {}
然后我们就需要在 createElement 内里做范例判定,假如我们碰着的 type 是字符范例,就按本来的方法处理惩罚。假如我们碰着是其他环境,我们就实例化传过来的 type。
function createElement(type, attributes, ...children) { // 建设元素 let element; if (typeof type === 'string') { element = document.createElement(type); } else { element = new type(); } // 挂上属性 for (let name in attributes) { element.setAttribute(name, attributes[name]); } // 挂上所有子元素 for (let child of children) { if (typeof child === 'string') child = document.createTextNode(child); element.appendChild(child); } // 最后我们的 element 就是一个节点 // 所以我们可以直接返回 return element; }
这里我们尚有一个问题,我们有什么步伐可以让自界说标签像我们普通 HTML 标签一样操纵呢?在最新版的 DOM 尺度内里是有步伐的,我们只需要去注册一下我们自界说标签的名称和范例。
可是我们现行较量安详的欣赏版本内里,照旧不太发起这样去做的。所以在利用我们的自界说 element 的时候,照旧发起我们本身去写一个接口。
首先我们是需要成立标签类,这个类能让任何标签像我们之前普通 HTML 标签的元素一样最后挂載到我们的 DOM 树上。
它会包括以下要领:
mountTo() —— 建设一个元素节点,用于后头挂載到 parent 父级节点上
setAttribute() —— 给元素挂上所有它的属性
appendChild() —— 给元素挂上所有它的子元素