呼叫方法
import {createElement, render} from './self-jsx';
let objJSX = createElement(
'div',
{id: 'box', className: 'box', style: {color: 'red'}},
createElement(
'h2',
{className: 'title'},
'\u7CFB\u7EDF\u63D0\u793A'
),
createElement(
'div',
{className: 'content'},
'\u6E29\u99A8\u63D0\u793A\uFF1A\u8BED\u6CD5\u9519\u8BEF\uFF01'
),
'\u672C\u64CD\u4F5C\u5C31\u662F\u4E00\u4E2A\u6D4B\u8BD5\uFF01'
);
render(objJSX, root);
複製程式碼
createElement
方法
/*
* CREATE-ELEMENT:建立JSX物件
* 引數:至少兩個 TYPE/PROPS,CHILDREN這個部分可能沒有可能有多個
*/
function createElement(type, props, ...childrens) {
props = props || {} // 下面要用in方法
let ref, key;
if ('ref' in props) {
ref = props['ref'];
props['ref'] = undefined;
}
if ('key' in props) {
key = props['key'];
props['key'] = undefined;
}
return {
type,
props: {
...props,
children: childrens.length <= 1 ? (childrens[0] || '') : childrens
},
ref,
key
};
}
複製程式碼
render
方法
function render(objJSX, container, callBack) {
let {type, props} = objJSX,
{children} = props;
let newElement = document.createElement(type);
for (let attr in props) {
if (!props.hasOwnProperty(attr)) break;
let value = props[attr];
if (value == undefined) continue;//=>NULL OR UNDEFINED
// 當是事件屬性的時候
let regEvent = /^on/;
if(regEvent.test(attr)){
newElement.addEventListener(attr.toUpperCase().substr(2)
,value.bind(undefined));
continue;
}
switch (attr.toUpperCase()) {
case 'CLASSNAME':
newElement.setAttribute('class', value);
break;
case 'STYLE':
for (let styleAttr in value) {
if (value.hasOwnProperty(styleAttr)) {
newElement['style'][styleAttr] = value[styleAttr];
}
}
break;
case 'CHILDREN':
/*
* 可能是一個值:可能是字串也可能是一個JSX物件
* 可能是一個陣列:陣列中的每一項可能是字串也可能是JSX物件
*/
//->首先把一個值也變為陣列,這樣後期統一運算元組即可
!(value instanceof Array) ? value = [value] : null;
value.forEach((item, index) => {
//->驗證ITEM是什麼型別的:如果是字串就是建立文字節點,如果是物件,我們需要再次執行RENDER方法,把建立的元素放到最開始建立的大盒子中
if (typeof item === 'string') {
let text = document.createTextNode(item);
newElement.appendChild(text);
} else {
render(item, newElement);
}
});
break;
default:
newElement.setAttribute(attr, value);
}
}
container.appendChild(newElement);
callBack && callBack();
}
export {
createElement,
render
};
複製程式碼