节点操作(增加) /案例:下拉菜单/案例:简单版发布留言

节点操作
因为利用DOM提供的方法获取元素逻辑性不强且非常繁琐

因此学习利用节点层级关系获取元素:

利用父子兄的关系获取元素
逻辑性强,但兼容性差
节点:页面中所有的内容都是节点(标签,属性,文本,注释等),在DOM中,节点使用node来获取
HTML DOM树中的所有节点都可以通过JS来访问,所有HTML元素都可以被修改,也可以创建或者删除
节点至少有:nodeType(节点类型)、nodeName(节点名称)、nodeValue(节点值)这三个基本属性

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

  <body>
    <div class="box">
      <span class="erweima"></span>
    </div>
    <script>
        //1.父节点 parentNode
        var erweima = document.querySelector('.erweima');
        //以往得到box节点
        var box = document.querySelector('box');
        console.log(erweima.parentNode);  //通过erweima的父节点得到box节点 
    </script>

得到的是离元素最近的父节点(就近原则),如果找不到父节点,就返回为空(null)



子节点 childNodes

以此为例:

    <ol>
      <li></li>
      <li></li>
      <li></li>
    </ol>
    <ul>
      <li></li>
      <li></li>
      <li></li>
    </ul>

1. 方法一:

element.childNodes :这样得到的是所有的子节点,包括 元素节点、文本节点等
如果只想要获得里面的元素节点,还需要做出一些处理ul.childNodes[i].nodeType == 1
元素节点 nodeType 为 1、属性节点 nodeType 为 2、文本节点 nodeType 为 3
 

    //2.子节点
     var ul = document.querySelector("ul");
     console.log(ul.childNodes); //这样得到的是所有的子节点,包括 元素节点、文本节点等
     //如果只想要获得里面的元素节点,还需要做出一些处理
     for (var i = 0; i < ul.childNodes; i++) {
     for (var i = 0; i < ul.childNodes; i++) {
       //ul.childNodes[i] 是元素节点
       console.log(ul.childNodes[i]);
     }
  }

但上述方法较为麻烦。不常用

2. 方法二

children 获取所有的子元素节点 是常用的开发技术

      //children 获取所有的子元素节点 是常用的开发技术
      console.log(ul.children);

firstChild 返回第一个子节点,无论是文本节点还是元素节点
lastChild 返回最后一个子节点,无论是文本节点还是元素节点
firstElementChild 返回第一个子元素节点 ie9才支持(存在兼容性问题)

      console.log(ol.firstChild);
      console.log(ol.lastChild);
      console.log(ol.firstElementChild);

特殊地:如果想获得第i个子元

素的方法为:element.children[i]

     //特殊地:如果想获得第i个子元素的方法为:element.children[i]
      var ol = document.querySelector("ol");
      console.log(ol.children[0]); //获得第一个元素
      console.log(ol.children[ol.children.length - 1]); //获得最后一个元素

案例一: 下拉菜单

分析:导航栏里面的li都要有鼠标经过效果,所以需要循环注册鼠标事件
核心原理:当鼠标经过li里面的 第二个孩子 ul 显示,当鼠标离开 则ul隐藏
代码:

 <style>
      * {
        padding: 0;
        margin: 0;
      }
      li {
        list-style-type: none;
      }
      a {
        text-decoration: none;
      }
      .nav {
        margin: 100px auto;
        width: 400px;
      }
      .nav > li {
        position: relative;
        display: inline-block;
        height: 41px;
        line-height: 41px;
        text-align: center;
        height: 41px;
        width: 80px;
      }
      .nav > li:hover {
        background-color: #eee;
      }
      .nav ul {
        display: none; /*初始时下来菜单隐藏起来*/
        position: absolute;
        top: 41px;
        left: 0;
        width: 100%;
      }
      .nav ul li {
        display: block;
        margin: 0 -2.5px 0px -2.5px;
        border-left: 1px solid #fecc58;
        border-right: 1px solid #fecc58;
        border-bottom: 1px solid #fecc58;
      }
      .nav ul li:hover {
        background-color: #fff5da;
      }
    </style>
  </head>
  <body>
    <ul class="nav">
        <li>
          <a href="#">微博</a>
          <ul>
            <li><a herf="#">关注</a></li>
            <li><a herf="#">关注</a></li>
            <li><a herf="#">关注</a></li>
          </ul>
        </li>
        <li>
           ....
        </li>重复
   </ul>
 <script>
      //分析:导航栏里面的li都要有鼠标经过效果,所以需要循环注册鼠标事件
      //核心原理:当鼠标经过li里面的 第二个孩子 ul 显示,当鼠标离开 则ul隐藏
      var nav = document.querySelector(".nav");
      var lis = nav.children; //得到四个li
      for (var i = 0; i < lis.length; i++) {
        lis[i].onmouseover = function () {
          this.children[1].style.display = "block";
        };
        lis[i].onmouseout = function () {
          this.children[1].style.display = "none";
        };
      }
    </script>
 </body>

兄弟节点
node.nextSibling 得到的是下一个兄弟节点,包括元素节点或者文本节点,找不到则返回空
node.previousSibling 得到的是上一个兄弟节点,包括元素节点或者文本节点,找不到则返回空
nextElementSibling 得到的是下一个兄弟元素节点(存在兼容性问题 ie9以上支持)
previousElementSibling 得到的是上一个兄弟节点 (存在兼容性问题 ie9以上支持)
 

<body>
    <div>div</div>
    <span>span</span>
    <script>
      var div = document.querySelector("div");
      //nextSibling 得到的是下一个兄弟节点,包括元素节点或者文本节点,找不到则返回空
      console.log(div.nextSibling); //返回 span 的元素节点
      //previousSibling 得到的是上一个兄弟节点,包括元素节点或者文本节点,找不到则返回空
      console.log(div.previousSibling); //返回 null
      //nextElementSibling  得到的是下一个兄弟元素节点(存在兼容性问题 ie9以上支持)
      console.log(div.nextElementSiblinshang);
      //previousElementSibling  得到的是上一个兄弟节点 (存在兼容性问题 ie9以上支持)
      console.log(div.previousElementSibling);
    </script>
  </body>

可以通过自己封装一个兼容性的函数来解决不兼容的问题

   //可以通过自己封装一个兼容性的函数
      function getextElementSibling(element) {
        var el = element;
        while ((el = el.nextSibling)) {
          if (el.nodeType === 1) {
            return el;
          }
        }
        return null;
      }

创建/添加节点
1.创建节点
document.creatElement('target') node 是被创建的节点,此方法创建由 tagName 指定的 HTML 元素 。因为这些元素原先并不存在,是根据我们的需求动态生成的,因此也称为动态创建元素节点

2. 添加节点
(1)node.appendChild(child) node是父节点 child 是子节点 ,将一个节点添加到指定父节点的子节点列表末尾(追加元素)在后面添加,类似于css里面的after伪元素
(2)node.insertBefore(child,指定元素) 在指定元素前面添加,
 

  <body>
    <ul></ul>
    <script>
      //1.创建节点 createElement("node") node 是被创建的节点
      var li = document.createElement("li");
      //2.添加节点  node.appendChild(child) 
      // node是父节点 child 是子节点 
      //将一个节点添加到指定父节点的子节点列表末尾
      //(追加元素)后面添加
      var ul = document.querySelector("ul");
      ul.appendChild(li);
      //node.insertBefore(child,指定元素)
      //在指定元素前面添加
      var lili = document.createElement('li');
      ul.insertBefore(lili,ul.children[0]);
    </script>
  </body>

我们想在页面中添加一个新的元素,分为两步:
1.创建元素 2.添加元素

案例二:简单版发布留言
案例分析:

核心思路:点击按钮之后,就动态创建一个li,添加到ul里面
创建li的同时,把文本域里面的值通过li.innerHTML赋值给li
如果想要新的留言在后面显示就用appendChild ,如果想要在前面显示就用insertBefore
 

   <body>
    <textarea name="" id=""></textarea>
    <button>发布</button>
    <ul></ul>
    <script>
      var btn = document.querySelector("button");
      var text = document.querySelector("textarea");
      var ul = document.querySelector("ul");
      btn.onclick = function () {
        if (text.value == null) {
          alert("您没有输入内容");
        } else {
          //创建元素
          var li = document.createElement("li");
          //把文本域的值传递给新创建的节点
          li.innerHTML = text.value;
          //添加元素
          ul.appendChild(li); //新的放在后面
          ul.insertBefore(li, ul.children[0]); //新的放在前面
        }
      };
    </script>
  </body>

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值