美文网首页
节点操作--父子节点

节点操作--父子节点

作者: 潘肚饿兵哥哥 | 来源:发表于2020-09-17 23:04 被阅读0次

    \color{rgba(254, 67, 101, .8)}{1.学习节点操作的目的:}

    学习节点操作的目的还是为了获取元素,获取元素的常用 两种方式:
    1.利用DOM提供的方法(API)获取元素
    例如:document.getElementById();document.getElementByTagName();document.queyrSelector();
    之前的这些方法很繁琐,且逻辑性不强
    \color{rgba(254, 67, 101, .8)}{所以学习利用节点的层级关系获取元素}

    \color{rgba(254, 67, 101, .8)}{利用节点的层级关系获取元素:}

    利用父子兄节点关系获取元素
    逻辑性强,但是兼容性稍差
    一般的,节点至少拥有nodeType(节点类型)和nodeName(节点名称)和nodeValue(节点值)三个基本属性

    这些值是规定的:

    • 元素节点 nodeType 值为 1
    • 属性节点 nodeType 值为 2
    • 文本节点nodeType 值为 3(文本节点包含文字、空格、换行等)
      \color{rgba(254, 67, 101, .8)}{在实际开发中,节点操作主要是操作元素节点}

    \color{rgba(254, 67, 101, .8)}{box这个对象中就有这三个属性}

        <!-- 节点的优点 -->
        <div>我是div</div>
        <span>我是span</span>
        <ul>
            <li>我是li</li>
            <li>我是li</li>
            <li>我是li</li>
            <li>我是li</li>
        </ul>
        <div class="box">
            <span class="erweima">×</span>
        </div>
        <script>
            var box = document.querySelector('.box');
            //打印这个元素对象
            console.dir(box);
        </script>
    
    image.png

    \color{rgba(254, 67, 101, .8)}{节点层级:}

    利用DOM树可以把节点划分为不同的层级关系,常见的是父子兄层级关系

    \color{rgba(254, 67, 101, .8)}{1.父级节点}
    node.parentNode
    它拿到的是离他最近的上一层,如果找不到父节点返回null

    \color{rgba(254, 67, 101, .8)}{2.子级节点}
    1.parentNode.childNodes(标准)
    parentNode.childNodes返回包含指定节点的子节点的集合,该集合为即时更新的集合
    注意:返回值里面包含了所有子节点,包括元素节点、文本节点等
    如果只想获得里面的元素节点需要专门处理,所以一般不提倡使用childNodes,需要用循环取:

    //如果要取到变迁中的元素,需要用下面的方法循环去取,所以,一般不提倡使用childNodes
            var ul = document.querySelector('ul');
            for (var i = 0; i < ul.childNodes; i++) {
                if (ul.childNodes[i].nodeType == 1) {
                    //ul.childNodes[i]是元素节点
                    console.log(ul.childNodes[i]);
                }
            }
    
        <!-- 节点的优点 -->
        <div>我是div</div>
        <span>我是span</span>
        <ul>
            <li>我是li</li>
            <li>我是li</li>
            <li>我是li</li>
            <li>我是li</li>
        </ul>
        <div class="box">
            <span class="erweima">×</span>
        </div>
        <!-- <script>
            // var box = document.querySelector('.box');
            // //打印这个元素对象
            // console.dir(box);
    
            //1.父节点node.parentNode
            //从前的写法:
            var erweima = document.querySelector('.erweima');
            var box = document.querySelector('.box');
            //现在如果想要拿到box,就按下面这样写:
            //他拿到的是离他最近的,他的上一层,如果找不到父节点返回null
            console.log(erweima.parentNode);;
        </script> -->
    
    
        <script>
            //以前要拿ul里面的li要写两行,拿两次才行:
            //利用DOM提供的方法(API)获取
            var ul = document.querySelector('ul');
            var lis = ul.querySelectorAll('li');
    
            //子节点:parentNode.childNodes(标准)
            console.log(ul.childNodes);
        </script>
    

    之所以有9个节点,是因为ul标签到li标签之间是默认有一个换行的,这个换行是text属性,而且每一个li之间也有一个换行,就是每换一次行有一个text

    image.png

    \color{rgba(254, 67, 101, .8)}{上面的childnodes太繁琐,一般不用}
    \color{rgba(254, 67, 101, .8)}{获取子节点第二种方法:}
    \color{rgba(254, 67, 101, .8)}{这种方法只会拿到子元素节点,这种才是最常用的}

    console.log(ul.children);
    
    image.png

    \color{rgba(254, 67, 101, .8)}{第一个子元素和最后一个子元素}

    子节点:
    parentNode.firstChild firstChild返回第一个子节点,找不到则返回null,同样,也是包含所有的节点,返回值带换行等节点
    parentNode.lastChild返回最后一个子节点,返回值带换行等节点

        <ol>
            <li>我是li1</li>
            <li>我是li2</li>
            <li>我是li3</li>
            <li>我是li4</li>
        </ol>
    
        <script>
            //获取元素
            var ol = document.querySelector('ol');
    
            //parentNode.firstChild返回第一个子节点
            //parentNode.firstChild返回最后一个子节点
            //返回的还是9个节点,连换行都在其中.所以下面代码返回的都是text
            console.log(ol.firstChild);
            console.log(ol.lastChild);
    
    image.png

    \color{rgba(254, 67, 101, .8)}{上面的两种方法不好用,还有其他方法:}

    有兼容性问题,IE9以上才支持
    parentNode.firstElementChild返回第一个子元素(不带换行等节点)
    parentNode.lastElementChild返回最后一个子元素(不带换行等节点)

    实际开发中,firstChild和lastChild包含其他节点,操作不便,而firstElementChild和lastElementChild又有兼容问题,解决方案如下:
    1.如果想要第一个元素节点,可以使用parentNode.children[0];

        <ol>
            <li>我是li1</li>
            <li>我是li2</li>
            <li>我是li3</li>
            <li>我是li4</li>
        </ol>
    
        <script>
            //获取元素
            var ol = document.querySelector('ol');
    
            //parentNode.firstChild返回第一个子节点
            //parentNode.firstChild返回最后一个子节点
            //返回的还是9个节点,连换行都在其中.所以下面代码返回的都是text
            console.log(ol.firstChild);
            console.log(ol.lastChild);
    
            //parentNode.firstElementChild返回第一个子元素,不代换行,比上面那两个好用
            console.log(ol.firstElementChild);
            console.log(ol.lastElementChild);
    
            //实际开发中,既没有兼容问题,又返回第一个子元素:
            console.log(ol.children[0]);
            console.log(ol.children[3]);
        </script>
    
    image.png

    \color{rgba(254, 67, 101, .8)}{案例:下拉菜单}

    分析:
    1..nav ul { /* 先把弹出列表项隐藏起来 */ display: none; }
    2.导航栏里面的li都要有鼠标经过的效果,所以要循环注册鼠标事件
    3.原理:当鼠标经过li里面的第二个孩子ul显示,当鼠标离开,ul隐藏

    \color{rgba(254, 67, 101, .8)}{代码实现:}

        <style>
            * {
                margin: 0;
                padding: 0;
            }
            
            li {
                list-style-type: none;
            }
            
            a {
                text-decoration: none;
                font-size: 14px;
            }
            
            .nav {
                margin: 100px;
            }
            
            .nav>li {
                position: relative;
                float: left;
                width: 80px;
                height: 41px;
                text-align: center;
            }
            
            .nav li a {
                display: block;
                width: 100%;
                height: 100%;
                line-height: 41px;
                color: #333;
            }
            
            .nav>li>a:hover {
                background-color: #eee;
            }
            
            .nav ul {
                /* 先把弹出列表项隐藏起来 */
                display: none;
                position: absolute;
                top: 41px;
                left: 0;
                width: 100%;
                border-left: 1px solid #FECC5B;
                border-right: 1px solid #FECC5B;
            }
            
            .nav ul li {
                border-bottom: 1px solid #FECC5B;
            }
            
            .nav ul li a:hover {
                background-color: #FFF5DA;
            }
        </style>
    </head>
    
    <body>
        <ul class="nav">
            <li>
                <a href="#">微博</a>
                <ul>
                    <li>
                        <a href="">私信</a>
                    </li>
                    <li>
                        <a href="">评论</a>
                    </li>
                    <li>
                        <a href="">@我</a>
                    </li>
                </ul>
            </li>
            <li>
                <a href="#">微博</a>
                <ul>
                    <li>
                        <a href="">私信</a>
                    </li>
                    <li>
                        <a href="">评论</a>
                    </li>
                    <li>
                        <a href="">@我</a>
                    </li>
                </ul>
            </li>
            <li>
                <a href="#">微博</a>
                <ul>
                    <li>
                        <a href="">私信</a>
                    </li>
                    <li>
                        <a href="">评论</a>
                    </li>
                    <li>
                        <a href="">@我</a>
                    </li>
                </ul>
            </li>
            <li>
                <a href="#">微博</a>
                <ul>
                    <li>
                        <a href="">私信</a>
                    </li>
                    <li>
                        <a href="">评论</a>
                    </li>
                    <li>
                        <a href="">@我</a>
                    </li>
                </ul>
            </li>
        </ul>
    
    
        <script>
            //1.获取元素
            var nav = document.querySelector('.nav');
            //2.获取ul的四个小li
            var lis = nav.children;
            //3.循环注册事件
            for (var i = 0; i < lis.length; i++) {
                lis[i].onmouseover = function() {
                    //鼠标经过,让li里面的ul显示
                    //block:正常显示,none:不显示,隐藏
                    this.children[1].style.display = 'block';
                }
                lis[i].onmouseout = function() {
                    //鼠标离开,隐藏
                    this.children[1].style.display = 'none';
                }
            }
        </script>
    
    新浪下拉菜单.gif

    相关文章

      网友评论

          本文标题:节点操作--父子节点

          本文链接:https://www.haomeiwen.com/subject/mqbgektx.html