javascript二——节点操作

节点操作

获取元素的两种方式:

  1. 利用DOM提供的方法获取元素
  • document.getElementById()
  • document.getElementByTagName()
  • document.querySelector
  • 逻辑性不强,繁琐
  1. 利用节点的层级关系获取元素
  • 利用父子兄弟节点关系获取元素
  • 逻辑性强,但是兼容性稍差

以上两种方式都可以获取元素节点,都会使用,但是节点操作更简单


什么是节点?

  • 网页中的所有内容都是节点(标签、属性、文本、注释等),在DOM中,节点使用node来表示。

  • HTML DOM树中的所有节点均可通过JavaScript进行访问,所有HTML元素(节点)均可被修改,也可以创建或删除。

  • 一般地,节点至少拥有nodeType(节点类型) 、nodeName(节点名称)和nodeValue(节点值)这三个基本属性。

    • 元素节点 nodeType 为 1
    • 属性节点 nodeType 为 2
    • 文本节点 nodeType 为 3 (文本节点包含文字、空格、换行等)
  • 实际开发中,节点操作主要操作的时元素节点


父节点操作

    <div class="box">
        <div class="erweima">x</div>
    </div>
    <script>
        //1.父节点 parentNode
        var erweima = document.querySelector('.erweima');
        //得到的是离元素最近的父级节点 如果找不到父节点就返回 null
        console.log(erweima.parentNode);
    </script>

子节点操作

  • firstElementChild 获取第一个子元素节点
  • lastElementChild 获取最后一个子元素节点
  • 这两个IE9以上才支持

实际开发中,firstchild和 lastchild包含其他节点,操作不方便,而firstElementChild和lastElementchild又有兼容性问题,那么我们如何获取第一个子元素节点或最后一个子元素节点呢?

解决方法

    <ul>
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
    </ul>
    <script>
        //DOM 提供的方法(API)获取
        var ul = document.querySelector('ul');
        var lis = ul.querySelectorAll('li');
        //1.子节点获取 包括元素节点、文本节点等
        // console.log(ul.childNodes);
        // console.log(ul.childNodes[0].nodeType);
        for (var i = 0; i < ul.childNodes.length; i++) {
            if (ul.childNodes[i].nodeType == 1) {
                //ul.childNodes[i] 是元素节点
                console.log(ul.childNodes[i]);
            }
        }
        //2. children 获取所有的子元素节点 常用
        console.log(ul.children);
        //1. firstChild 拿到的是第一个子节点 不管是文本节点还是元素节点
        console.log(ul.firstChild);
        console.log(ul.lastChild);
        //2. firstElementChild 返回第一个子元素
        console.log(ul.firstElementChild);
        console.log(ul.lastElementChild);
        //3. 实际开发的写法 既没有兼容性问题又返回第一个子元素
        console.log(ul.children[0]);
        console.log(ul.children[ul.children.length - 1]);//最后一个
    </script>

兄弟节点

1.node.nextSibling  返回当前元素的下一个兄弟节点,找不到则返回null,也是包含所有节点
2.node.previousSibling 上一个兄弟节点
3.node.nextElementSibling  返回下一个兄弟元素节点,找不到返回null
4.node.previousElementSibling 上一个 

注:3.4方法有兼容性问题,IE9以上才支持

    <div>我是div</div>
    <span>我是span</span>
    <script>
        var div = document.querySelector('div');
        //下一个兄弟节点
        console.log(div.nextSibling);
        //上一个
        console.log(div.previousSibling);
        //下一个兄弟元素节点
        console.log(div.nextElementSibling);
        //上一个
        console.log(div.previousElementSibling);
    </script>

创建节点

document.createElement('tagName')

document.createElement(〉方法创建由tagName 指定的 HTML元素。因为这些元素原先不存在,是根据我们的需求动态生成的,所以我们也称为动态创建元素节点。

添加节点

1.node.appendChild(child)
//将一个节点添加到指定父节点的子节点列表末尾
2.node.insertBefore(child,指定元素)
//添加到父节点的指定子节点的前面
    <ul>
        <li>123</li>
    </ul>
    <script>
        var ul = document.querySelector('ul');
        //1.创建元素节点
        var li = document.createElement('li');
        //2.添加节点 node.appendChild(child) node 父级 child子级
        ul.appendChild(li);
        li.innerHTML = 'hello';
        //3.添加节点 node.insertBefore()
        var lili = document.createElement('li');
        ul.insertBefore(lili, ul.children[0]);
        lili.innerHTML = 'feliks';
    </script>

留言板案例

    <textarea name="" id="" cols="30" rows="10">123</textarea>
    <button>submit</button>
    <ul>
        <li>123</li>
    </ul>
    <script>
        var txt = document.querySelector('textarea');
        var btn = document.querySelector('button');
        var ul = document.querySelector('ul');
        btn.onclick = function() {
            if (txt.value == '') {
                alert('请输入内容');
                return false;
            } else {
                var li = document.createElement('li');
                //现有li再赋值
                li.innerHTML = txt.value;
                // ul.appendChild(li);
                ul.insertBefore(li, ul.children[0]);
                //清空文本域
                txt.value = '';
            }

        }
    </script>

删除节点

node.removeChild(child)
//从DOM中删除一个子节点,返回删除的节点
   <ul>
       <li>1</li>
       <li>2</li>
       <li>3</li>
   </ul>
   <button>删除</button>
   <script>
       var btn = document.querySelector('button');
       var ul = document.querySelector('ul');
       // var lis = document.querySelectorAll('li');
       btn.onclick = function() {
           if (ul.children.length == 0) {
               this.disabled = true;
           } else {
               ul.removeChild(ul.children[0]);
           }
       }
   </script>

删除留言

    <textarea name="" id="" cols="30" rows="10">123</textarea>
    <button>submit</button>
    <ul>
        <!-- <li>123</li> -->
    </ul>
    <script>
        var txt = document.querySelector('textarea');
        var btn = document.querySelector('button');
        var ul = document.querySelector('ul');
        btn.onclick = function() {
            if (txt.value == '') {
                alert('请输入内容');
                return false;
            } else {
                var li = document.createElement('li');
                //现有li再赋值
                li.innerHTML = txt.value + "<a href='javascript:;'>删除</a>";
                // ul.appendChild(li);
                ul.insertBefore(li, ul.children[0]);
                //清空文本域
                txt.value = '';
                //删除元素
                var as = document.querySelectorAll('a');
                for (var i = 0; i < as.length; i++) {
                    as[i].onclick = function() {
                        //儿子让爷爷把爸爸干掉
                        ul.removeChild(this.parentNode);
                    }
                }
            }

        }
    </script>

复制节点

node.cloneNode()//浅拷贝
node.cloneNode(true)//深拷贝
//返回调用该方法的节点的一个副本

注:如果括号参数为空或为false,则是浅拷贝,只克隆节点本身,不克隆里面的子节点

<body>
    <ul>
        <li>1</li>
        <li>2</li>
        <li>3</li>
    </ul>
    <script>
        var ul = document.querySelector('ul');
        var li = ul.children[0].cloneNode(true);
        ul.appendChild(li);
    </script>
</body>

动态生成表格案例

<body>
    <table cellspacing="0">
        <thead>
            <tr>
                <th>姓名</th>
                <th>科目</th>
                <th>成绩</th>
                <th>操作</th>
            </tr>
        </thead>
        <tbody>

        </tbody>
    </table>
    <script>
        var datas = [{
            name: 'feliks',
            subject: 'javascript',
            score: '100'
        }, {
            name: 'slugger',
            subject: 'javascript',
            score: '98'
        }, {
            name: 'spiderman',
            subject: 'javascript',
            score: '101'
        }, {
            name: 'ironman',
            subject: 'javascript',
            score: '99'
        }];
        //1.往tbody里放行 有几个人就创建几行
        var tbody = document.querySelector('tbody');
        for (var i = 0; i < datas.length; i++) {
            //2.创建tr
            var tr = document.createElement('tr');
            tbody.appendChild(tr);
            //3.行里创建单元格 td 单元格的数量取决于每个对象的属性个数
            for (var k in datas[i]) {
                var td = document.createElement('td');
                td.innerHTML = datas[i][k];
                tr.appendChild(td);
            }
            //创建删除单元格
            var td = document.createElement('td');
            td.innerHTML = '<a href="javascropt:;">删除</a>';
            tr.appendChild(td);
        }
        //4.删除操作 开始
        var as = document.querySelectorAll('a');
        for (var i = 0; i < as.length; i++) {
            as[i].onclick = function() {
                //点击删除当前a所在的行(a的爸爸的爸爸)
                tbody.removeChild(this.parentNode.parentNode);
            }
        }
        // for(var k in obj){
        //     k得到的是属性名
        //     obj[k] 得到的是属性值
        // }

三种动态创建元素的区别

  • document.write()
  • element.innerHTML
  • document.createElement()

区别

  1. document.write()是直接将内容写入页面的内容流,但是文档流执行完毕,则它会导致页面的全部重绘
  2. innerHTML 是将内容写入某个DOM节点,不会导致页面全部重绘
  3. innerHTML 创建多个元素效率更高(不要拼接字符串,采取数组形式拼接),结构稍复杂
  4. createElement() 创建多个元素效率低一点点,但是结构更清晰

总结:不同浏览器下,innerHTML 效率要比 createElement 高

var btn = document.querySelector('button');
btn.onclick = function(){
    document.write('<div>123</div>');
}
//这样会导致页面重绘
    <div class="inner"></div>
    <div class="create"></div>
    <script>
        //innerHTML 创建元素
        var d1 = +new Date();
        var inner = document.querySelector('.inner');
        // for (i = 0; i < 100000; i++) {
        //     inner.innerHTML = '<a href="javascript:;">hello</a>'
        // }//耗时962

        // ==
        //==数组拼接
        var arr = [];
        for (i = 0; i < 100000; i++) {
            arr.push('<a href="javascript:;">hello</a>');
        }
        inner.innerHTML = arr.join('');//耗时300
        var d2 = +new Date()
        console.log(d2 - d1); //innerHTML耗时

        
        //document.createElement()创建元素
        var create = document.querySelector('.create');
        for (i = 0; i < 100000; i++) {
            var a = document.createElement('a');
            create.appendChild(a);
        }
        var d3 = +new Date();
        console.log(d3 - d2); //createElement耗时:145
    </script>

DOM核心重点

文档对象模型(Document Object Model,简称DOM),是W3C组织推荐的处理可扩展标记语言(HTML或者XML)的标准编程接口
W3C已经定义了一系列的DOM接口,通过这些DOM接口可以改变网页的内容、结构和样式。

  1. 对于JavaScript,为了能够使JavaScript操作HTML,JavaScript就有了一套自己的dom编程接口。
  2. 对于HTML,DOM 使得HTML形成一棵DOM树,包含文档、元素、节点

我们获取过来的DOM元素是一个对象(object),所以成为文档对象模型


关于DOM操作,我们主要针对元素的操作。主要有创建、增删改查、属性操作、事件操作。

创建

  1. document.write
  2. innerHTML
  3. createElement

  1. appendChild
  2. insertBefore

  1. removeChild

主要修改DOM的元素属性,DOM元素的内容、属性,表单的值等

  1. 修改元素属性:src, href, title 等
  2. 修改普通元素内容:innerHTML, innerText
  3. 修改表单元素:value, type, disable等
  4. 修改元素样式:style, className

主要获取查询DOM的元素

  1. DOM提供的API方法:getElementById, getElementsByTagName 古老用法不推荐
  2. H5提供的新方法: querySelector、querySelectorAll 提倡
  3. 利用节点操作获取元素:父(parentNode)、子(children)、兄弟(previousElementSibling、nextElementSibling) 提倡

属性操作

主要针对于自定义属性

  1. setAttribute: 设置DOM的属性值
  2. getAttribute: 得到DOM的属性值
  3. removeAttribute 移除属性

事件操作

给元素注册事件,采取 事件源.事件类型 = 事件处理程序

鼠标事件触发条件
onclick鼠标点击左键触发
onmouseover鼠标经过触发
  • 5
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值