SOURCE

console 命令行工具 X clear

                    
>
console
<html>
    <body>
		<button onclick="createUl()">生成节点</button>
		<button onclick="update()">更新节点</button>
		<div class="list" id="mian">
			<ul>
				<li>你好</li>
				<li>李红艳</li>
			</ul>
		</div>
    </body>
<script>

Element.prototype.render = function() {
let el = document.createElement(this.tagName),
    props = this.props,
    propName,
    propValue;
for (propName in props) {
    propValue = props[propName]
    el.setAttribute(propName, propValue)
}
this.children.forEach(function(child) {
let childEl = null
if (child instanceof Element) {
    childEl = child.render()
} else {
    childEl = document.createTextNode(child)
}
    el.appendChild(childEl)
})

return el
}


const elem = Element({
tagName: 'ul',
props: {
'class': 'list2'
},
children: [
Element({
tagName: 'li',
children: ['item2'],
props: {
    'class': 'item_1'
}
}),
Element({
tagName: 'li',
children: ['item2'],
props: {
    'class': 'item_1'
}
})
]
})

function createUl() {
let sele = document.querySelector("body").appendChild(elem.render())
console.log('sele', sele)
}


//构造Dom函数
function Element({
tagName,
props,
children
}) {
if (!(this instanceof Element)) {
return new Element({
tagName,
props,
children
})
}
this.tagName = tagName
this.props = props || {}
this.children = children || {}
}



function update() {
const body = document.querySelector('body')
const list = document.querySelector('.list2')
const newElem = Element({
tagName: 'ul',
props: {
'class': 'list3'
},
children: [
Element({
    tagName: 'li',
    children: ['1111111'],
    props: {
        'class': 'item_1'
    }
})
]
})

updateElement(body, newElem, elem)
}

//更新Dom函数,更新就三种,删除,更改,新增
function changed(elem1, elem2) {
// const result = (typeof elem1 !== typeof elem2) ||
// 	(typeof elem1 === 'string' && elem1 !== elem2) ||
// 	(elem1.type !== elem2.type);
const result = JSON.stringify(elem1) !== JSON.stringify(elem2) ||
typeof elem1 === 'string' && elem1 !== elem2
return result
}


function updateElement($root, newElem, oldElem, index = 0) {

if (!oldElem) {
$root.appendChild(newElem.render())
} else if (!newElem) {
$root.removeChild($root.childNodes[index])
} else if (changed(newElem, oldElem)) {
console.log('newElem', newElem, 'index', index, '$root', $root)
if (typeof newElem === 'string') {
$root.childNodes[index].textContent = newElem
} else {
let newDom = newElem.render()
let oldDom = oldElem.render()
let innerHTML = oldDom.innerHTML
let childNodes = Array.from($root.childNodes)
let index = childNodes.findIndex(item => item.innerHTML === innerHTML)
if (index >= 0) {
    $root.replaceChild(newDom, $root.childNodes[index]) //$root.childNodes[index]
}

// for (let [index, item] of $root.childNodes.entries()) {
// 	if (item.innerHTML === innerHTML) {
// 		$root.replaceChild(newDom, $root.childNodes[index]) //$root.childNodes[index]
// 	}
// }


}
} else if (newElem.tagName) {
let newLen = newElem.children.length
let oldLen = oldElem.children.length
for (let i = 0; i < newLen || i < oldLen; i++) {
updateElement(
    $root.childNodes[index],
    newElem.children[i],
    oldElem.children[i],
    i)
}
}
}
</script>
</html>