节点操作--父子节点

2020-09-17  本文已影响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
上一篇下一篇

猜你喜欢

热点阅读