深说浅谈DOM对象,用4个版本demoplus让你扭断history.state头(更)

Posted 勇敢*牛牛

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了深说浅谈DOM对象,用4个版本demoplus让你扭断history.state头(更)相关的知识,希望对你有一定的参考价值。

深说浅谈DOM对象操作,用4个版本demoplus让你扭断history.state头

什么是节点

html 文档中的每个成分都是一个节点。

(1)节点类型

DOM 是这样规定的:

  • 整个文档是一个文档节点
  • 每个 HTML 标签是一个元素节点
  • 包含在 HTML 元素中的文本是文本节点
  • 每一个 HTML 属性是一个属性节点 注释属于注释节点

(2)节点层次关系-节点彼此都有等级关系。

HTML 文档中的所有节点组成了一个文档树(或节点树)。
HTML文档中的每个元素、属性、文本等都代表着树中的一个节点。
树起始于文档节点,并由此继续伸出枝条,直到处于这棵树最低级别的所有文本节点为止。
当节点分享同一个父节点时,它们就是同辈(同级节点)。
节点也可以拥有后代,后代指某个节点的所有子节点,或者这些子节点的子节点。
节点也可以拥有先辈。先辈是某个节点的父节点,或者父节点的父节点,以此类推。

(3)节点属性

每个节点都拥有包含着关于节点某些信息的属性。这些属性是:
nodeName(节点名称)
元素节点的 nodeName 是标签名称
文本节点的 nodeName 永远是 #text
注释节点的 nodeName 永远是 #comment
文本节点,nodeValue 属性包含文本。
节点nodeValue元素节点nodeValue不可用不可用
nodeValue包括注释内容
nodeType(节点类型)

获取body后节点列表

document.body.childNodes

<p>a</p>
<form action="">
    <input type="text" name="user" id="">
    <input type="radio" name="sex" value="男" class="input1">
    <input type="radio" name="sex" value="女" class="input2">
</form>

<div id="div2">
    <span class="div1"></span>
    <span class="div1"></span>
</div>
<span class="div1"></span>
 console.log(document.body.childNodes);
//text, p, text, comment, text, script
 console.log(document.body.childNodes[1].nodeName==="P");
 //true

获取DOM元素

document.documentElement  //html标签
document.body //body 标签
document.title //标题
//所有的style标签列表和link标签列表有多少个样式style就有多少length
方法名称调用描述
document.getElementById()通过元素的id值获取
document.getElementsByTagName()返回元素的HTML集合
document.getElementsByName()ame来获得对象,同一个Name可以对应多个对象(Name不是唯一的),所以它得到的是一个数组
document.getElementsByClassName(新)通过类名来获取 元素
document.querySelector( 新)根据标签名(类名)获取第一个元素
document.querySelectorAll(新)获取所有标签名的元素

querySelector的用法

在js中可以通过标签选择器获取标签,现在发现还有querySelector可以实现选择器的功能。可以是标签名,也可以是类名。

<p id="demo" class="demo_1">单击按钮获取按钮元素的节点值。</p>
<button onclick="myFunction()">点我</button>
<script>
console.log(document.getElementById('demo'));
console.log(document.querySelector('.demo_1'));
console.log(document.querySelector('p'));

getElementsByTagName的用法

传回指定名称的元素集合。也就是一个数组集合,所以用的时候得注意这个后面指定是哪个元素。

var c=document.getElementsByTagName("BUTTON")[0];

节点遍历

方法名称调用描述
childNodes所有子节点 获取所有子节点(包括注释)
children所有是标签类型的子节点 获取所有子元素
parentNode获取已知节点的父节点
firstElementChild第一个子节点 (元素)
firstChild第一个子节点
lastElementChild()最后一个子节点(元素)
lastChild:最后一个子节点
nextElementSiblin下一个兄弟节点(元素)
nextSibling下一个兄弟节点
previousElementSibling上一个兄弟节点
previousSibling上一个兄弟节点
document.createTextNode(“”)创建文本节点
<div id="div2">
    <span class="div1"></span>
    <span class="div1"></span>
</div>
console.log( div2.nextSibling);//#text
console.log(div2.childNodes);
//[text, span.div1, text, span.div1, text]
节点/元素 操作功能描述
document.createElement(“标签名”)创建新元素
父元素.appendChild()追加在尾部
父元素.insertBefore(要插入的元素,要插入在谁的前面)追加在谁之前
textContent获取包含换行符合空格的结构性文本
innerText获取父元素中所有文本和后代文本
innerHTML父元素中所有的html标签文本及内容
document.createTextNode(“”)创建文本节点
replaceChild(newNode,oldNode)newNode替换节点oldNode
removeChild(node)移除父节点的某个子节点
cloneNode(boolean)复制一个节点
被替换的元素.replaceWith(新元素)替换
父元素.replaceChild(新元素,被替换的元素)替换

innerText可以设置转义字符和空格换行等,textContent只能设置其文本,不能含转义,传统的获取渲染会丢失对象

DOM树
CSS树
DOM渲染树
异步加载渲染树
数据驱动显示

传统点击事件重新渲染丢失对象元素

<div id="div1">
    <span>1</span>
</div>

var div1=document.querySelector("#div1");
var span=div1.querySelector("span");
span.onclick = function()
     span.style.color = 'red'

div1.innerHTML+="<span>2</span>";
//这样会失去点击对象

dom创建元素直接添加渲染

不改变原来对象:

div id="div1">
    <span>1</span>
</div>

var span_1 = document.createElement('span')
span_1.textContent = '2'
div1.appendChild(span_1,span);
//创建一个dom对象(元素/标签)然后在给赋值
span.onclick = function()
     span.style.color = 'red'

//不会失去捕获对象

创建碎片容器(js创建一个table)

<script>
    // table.tr.dd
    /* 首先创建一个元素table */
    var table = document.createElement('table')
    
    for(var i=0;i<100;i++)
        //创建tr对象标签
        var tr = document.createElement('tr')
        for(var j=0;j<10;j++)
            // 创建td对象标签
            var td = document.createElement('td')
            // 给td添加内容
            td.textContent = '1'
            // 追加在这个父标签的最后位
            tr.appendChild(td)
        
        // 追加在这个父标签的最后位
        table.appendChild(tr)
    
    console.log(table);
    document.body.appendChild(table)
</script>

创建100个div插入到body中

var elem=document.createDocumentFragment();//创建碎片容器
for(var i=0;i<100;i++)
    var div=document.createElement("div");
    elem.appendChild(div);

document.body.appendChild(elem);

创建文本结点插在第一个子元素的前面

<div id="div1">
    <span>1</span>
</div>
var txtNode=document.createTextNode("3");
div1.insertBefore(txtNode,div1.firstChild);

只有img标签才可以new 创建

var img=document.createElement("img");
//var img=new Image();
img.src="./img/img_21.JPG"
document.body.appendChild(img);
var img1=img.cloneNode(false);
document.body.appendChild(img1);

删除元素

span.remove();
// 父元素删除子元素
div1.removeChild(span);
// 清空元素所有内容
div1.innerHTML="";

替换元素

var p=document.createElement("p");
// 父元素.replaceChild(新元素,被替换的元素)
document.body.replaceChild(p,div1)
// 被替换的元素.replaceWith(新元素)
div1.replaceWith(p)

添加内容(数据驱动显示)版本一

无历史记录版本,纯dom操作

<input type="text"> <button>点击添加</button>
<ul></ul>
<script>
    var input,button,ul;
    init();

    function init()
        /* 获取三个元素对象 */
        input = document.querySelector('input')
        button = document.querySelector('button')
        ul = document.querySelector('ul')
        /* 给button设置点击事件 */
        button.onclick = onclickHander;
    
    function onclickHander()
        /* 点击之后创建一个li元素 */
        var li = document.createElement('li') 
        console.log(input.value);
        li.textContent = input.value;
        ul.insertBefore(li,ul.firstChild);
        input.value = ''
    
           
    </script>
</body>

数据驱动显示,碎片容器打包渲染(版本二)

<body>
    <input type="text"> <button>点击添加</button>
    <ul></ul>
    <script>
        var input,button,ul;
        var list =[];
        init();

        function init()
            /* 获取三个元素对象 */
            // window.onpopstate = onclickHander;
            input = document.querySelector('input')
            button = document.querySelector('button')
            ul = document.querySelector('ul')
            // var li = history.state?
            /* 给button设置点击事件 */
            button.onclick = onclickHander;
        
        function onclickHander()
            /* 点击之后创建一个li元素 */
            // var li = document.createElement('li') 
            // console.log(input.value);
            list.push(input.value)
            upData();
            console.log(list);
            // ul.insertBefore(li,ul.firstChild);
            input.value = ''
            // history.pushState(li,li);
            // console.log(history.state);
        
        function upData()
            //每次渲染之前给ul清空内容
            ul.innerHTML = ''
            var emel = document.createDocumentFragment();
            for(var i=0;i<list.length;i++)
                var li = document.createElement('li');
                li.textContent = list[i];
                //每一次生成的li包裹在这emel胶囊中
                emel.appendChild(li)
            
            ul.append(emel)    
        
        
    </script>

新增删除按钮。添加属性标记条件,利于程序删除(版本三)

<input type="text"> <button>点击添加</button>
<ul></ul>
<script>
    var input,button,ul;
    var list =[];
    init();

    function init()
        /* 获取三个元素对象 */
        // window.onpopstate = onclickHander;
        input = document.querySelector('input')
        button = document.querySelector('button')
        ul = document.querySelector('ul')
        // var li = history.state?
        /* 给button设置点击事件 */
        button.onclick = onclickHander;
    
    function onclickHander()
        /* 点击之后创建一个li元素 */
        // var li = document.createElement('li') 
        // console.log(input.value);
        if(!input.value)
            return;
        
        list.push(input.value)
        upData();
        console.log(list);
        // ul.insertBefore(li,ul.firstChild);
        input.value = ''
        // history.pushState(li,li);
        // console.log(history.state);
    
    function upData()
        //每次渲染之前给ul清空内容
        ul.innerHTML = ''
        var emel = document.createDocumentFragment();
        for(var i=0;i<list.length;i++)
            var li = document.createElement('li');
            li.textContent = list[i];
            var bn = document.createElement('button');
            bn.innerHTML = '&times';
            bn.onclick = removeData;
            bn.i=i;
            li.append(bn)
            //每一次生成的li包裹在这emel胶囊中
            emel.appendChild(li)
        
        ul.append(emel)    
    
    function removeData()
        list.splice(this.i,1)
        upData()
    

添加history历史记录(版本四)

<!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>
    <input type="text"> <button>点击添加</button>
    <ul></ul>
        <script>
        var input,button,ul;
        var list =[];
        init();

        function init()
            /* 初始化启动history监听 */
            window.onpopstate = changehistoryHander;
            input = document.querySelector('input')
            button = document.querySelector('button')
            ul = document.querySelector('ul')
            button.onclick = onclickHander;
            /* 历史第一次替换为list */
            history.replaceState(list,'a')
        
        /* 把数据框的里值放在数组当中 */
        function onclickHander()
            if(!input.value)
                return;
            
            list.push(input.value)
            upData();
            console.log(list);   
            input.value = ''
            //添加历史状态
            history.pushState(list,'b')

       
        
         /* 数据驱动显示 */
        function upData()

            ul.innerHTML = ''
            var emel = document.createDocumentFragment();
            for(var i=0;i<list.length;i++)
                var li = document.createElement('li');
                li.textContent = list[i];
                var bn = document.createElement('button');
                bn.innerHTML = '&times';
                bn.onclick = removeData;
                bn.i=i;
                li.append(bn)
                emel.appendChild(li)
            
            ul.append(emel)    
        
        /* 过程中做好数据标识 */
        function removeData()
            list.splice(this.i,1)
            history.pushState(list,'c')
            upData()
        
        function changehistoryHander()
            list = history.state;
            upData()
        
    </script>
</body>
</html>

Dom属性

DOM 的对象属性 部分标签属性和对象属性是相通的
大部分系统默认的标签属性都是相通
自定义的标签属性是不相通的
class 是特殊的,在对象属性中使用className
表单\\超链接的name与对象属性name相同,但是其他元素的name不相通

<div id="div1" class="div2" name="abc" title以上是关于深说浅谈DOM对象,用4个版本demoplus让你扭断history.state头(更)的主要内容,如果未能解决你的问题,请参考以下文章

浅谈React虚拟DOM

Js之浅谈dom操作

浅谈JavaScript的事件(事件对象)

JavaScript DOM操作浅谈

9个问题浅谈自动化测试与测试用例的编写

浅谈虚拟DOM