JavaScript之DOM

一、DOM简介

文档对象模型(Document Object Model,简称DOM),是W3C组织推荐的处理可扩展标记语言(HTML或者XML)的标准编程接口

W3C已经定义了一系列的DOM接口,通过这些DOM接口可以改变网页的内容、结构和样式

1.DOM树

在这里插入图片描述
DOM把以下内容都看做是对象:

  • 文档:一个页面就是一个文档,DOM中使用document表示
  • 元素:页面中的所有标签都是元素,DOM中使用element表示
  • 节点:网页中的所有内容都是节点(标签、属性、文本、注释等),DOM中使用node表示

二、获取元素

DOM在我们实际开发中主要用来操作元素 获取页面中的元素可以使用以下几种方式

  • 根据ID获取
  • 根据标签名获取
  • 通过HTML5新增的方式索取
  • 特殊元素获取

1.根据ID获取

使用getElementByld()方法获取带有ID的元素对象

 <div id="time">2022-1-18</div>
  <script>
    // 1.因为我们文档页面从上往下加载,所以先得有标签 所以我们JavaScript写到标签的下面
    // 2.get 获得   Element 元素    by 通过
    // 3.参数Id是大小写敏感的字符串
    // 4.返回的是一个元素对象
   var time2 = document.getElementById('time');
   console.log(time2);
   console.dir(time2);//打印我们返回的元素对象 更好的查看里面的属性和方法
  </script>

2.根据标签名获取

使用getElementsByTagName()方法可以返回带有指定标签名的对象的集合

 <ul>
   <li>我是美女</li>
   <li>我是美女</li>
   <li>我是美女</li>
   <li>我是美女</li>
   <li>我是美女</li>
   <li>我是美女</li>
 </ul>
  <script>
  //  1.返回的是获取过来元素对象的集合,以伪数组的形式
   var lis = document.getElementsByTagName('li');
   console.log(lis);
   console.log(lis[0]);
  //  2.我们想要依次打印里面的元素对象可以用遍历
  for(var i = 0; i < lis.length; i++){
    console.log(lis[i]);
  }
  // 3.无论有多少个返回的都是伪数组的形式

还可以获取某个元素(父元素)内部所以指定标签名的子元素

element(父元素).getElementsByTagName(‘标签名’);
注意:父元素必须是指定的单个对象(必须指明是哪个元素对象),获取的时候不包括父元素自己

父类不能是伪数组,要以一个具体的数,不可以同时有很多父亲

<ul>
   <li>我是美女</li>
   <li>我是美女</li>
   <li>我是美女</li>
   <li>我是美女</li>
   <li>我是美女</li>
   <li>我是美女</li>
 </ul>
 <ol id="a">  <!--给ol唯一的id -->
   <li>帅哥</li>
   <li>帅哥</li>
   <li>帅哥</li>
   <li>帅哥</li>
 </ol>
 /*如何把ol里面的li获取?如果用document来获取的话是把页面中整个li获取过来
    可以获取某个元素(父元素)内部所以指定标签名的子元素element.getElementsByTagName('标签名');*/
   var b = document.getElementById('a');//先用getElementById来获取带有ID的元素
   console.log(b.getElementsByTagName('li'));//再获取某个元素内部所指定标签名的子元素集合

3.通过HTML5新增的方法获取

<div class="box">盒子</div>
  <div class="box">盒子</div>
  <div id="nav">
    <ul>
      <li>首页</li>
      <li>产品</li>
    </ul>
  </div>

document.getElementByClassName(‘类名’); //根据类名返回元素对象集合

// 1.getElementsByClassName 根据类名获得某些元素集合
    var boxs  = document.getElementsByClassName('box')
    console.log(boxs);

如果想要不用再分选择器获取的话:(但只能返回第一个元素)

document.querySelector(‘选择器’); //根据指定选择器返回第一个元素

 // 2.querySelector返回指定选择器的第一个元素对象 
    // 里面的元素需要加符号
    var firstBox = document.querySelector('.box');
    console.log(firstBox);
    var nav = document.querySelector('#nav');
    console.log(nav);
    var li = document.querySelector('li');
    console.log(li);

document.querySelectorAll(‘选择器’); //根据指定选择器返回 可以返回选择器里的全部

// 3.querySelectorAll() 返回指定选择器的所有的元素对象集合
    var allBox = document.querySelectorAll('.box');
    console.log(allBox);
    var lis = document.querySelectorAll('li');
    console.log(lis);

4.获取特殊元素

获取body元素

document.body / / 返回Body元素对象

var bodys = document.body;
 console.log(bodys);

获取html元素

document.documentElement / /返回html元素对象

var htmls = document.documentElement;
 console.log(htmls);

三、事件

1.事件三要素:

事件源:事件被触发的对象
事件类型:如何触发 什么事件 比如:鼠标点击(onclick) 鼠标经过 键盘按下
事件处理程序:通过函数赋值方式完成

<!-- 我想点击登录弹出一个对话框,需要事件来处理就必须经过事件三要素 -->
<body>
  <button id="a">登录</button>
  <script>
    // 1.获得事件源(btn)
    var btn = document.getElementById('a');
    //  2.事件类型 如何触发 (onclick)
    // 3.事件处理程序(用函数处理)
    btn.onclick = function(){
      alert('请先登录');
    }

  </script>

2.执行事件的步骤

1.获取事件源
2.注册事件(绑定事件)
3.添加事件处理程序(采用函数赋值形式)
常见的鼠标事件:
在这里插入图片描述

<div>123</div>
  <!-- 点击div控制台输出我被选中了 -->
  <script>
    // 1.获取事件源
    var div1 = document.querySelector('div');
    // 2.绑定事件 注册事件
    // div1.onclick
    // 3.添加事件处理程序
    div1.onclick = function () {
      console.log('我被选中了');
    }

  </script>

四、操作元素

JavaScript的DOM操作可以改变网页内容、结果和样式,我们可以利用DOM操作元素来改变元素里面的内容、属性等

1.改变元素的内容

element.innerText
从起始位置到终止位置的内容,但它去除html标签,同时空格和换行也会被去掉

element.innerHTML 使用的最多
起始位置到终止位置的全部内容,包括html标签,同时保留空格和换行

<!-- 当我们点击了按钮 div 里面的文字会发生变化 显示当前时间 -->
<style>
    div{
      width: 300px;
      height: 30px;
      line-height: 30px;
      color: aliceblue;
      background-color: pink;
    }
  </style>
</head>
<body>
  <button>显示当前系统时间</button>
  <div>某个时间</div>
  <script>
  // 1.获取元素
  var btn  = document.querySelector('button');
  var div1 = document.querySelector('div');
  // 2.注册事件 谁点击的是谁
  btn.onclick = function(){
    div1.innerText = getDate();
  }
 // 得到当前时间的函数
  function getDate(){
    var date = new Date();
    var year = date.getFullYear();
    var month = date.getMonth() + 1;
    var dates = date.getDate();
    var arr = ['星期日' ,'星期一','星期二','星期三','星期四','星期五','星期六'];
    var day = date.getDay();
    return '今天是'+year+'年'+month+'月'+dates+'日'+arr[day];
  }
// 元素可以不用直接添加事件
  var p = document.querySelector('p');
  p.innerText = getDate();

innerText 和 innerHTML的区别:

<div></div>
<script>
  // 1.innerText 不识别HTML标签  非标准 去除空格和换行
  var div = document.querySelector('div');
  div.innerText = '今天是:2019';
  // 2.innerHTMl 识别HTML标签  保留空格和换行
  div.innerHTML = '<strong>今天是:2019</strong>';
  // 这两个属性是可读写的 可以获取元素里面的内容

</script>

2.修改元素属性

点击按钮修改元素内容

 <!-- 点击按钮1图片变成另一张图片 点击按钮2再变回来 -->
<style>
    img {
      display: block;
      width: 300px;
    }
  </style>
</head>

<body>
  <button id="mn1">头像1</button>
  <button id="mn2">头像2</button>
  <img src="../DOM.html/IMG_3204.jpg" alt="" title="美女1">
  <script>
    // 修改元素属性
    // 1.获取元素
    var tx1 = document.getElementById('mn1');
    var tx2 = document.getElementById('mn2');
    var img = document.querySelector('img');
    // 2.注册事件
    tx1.onclick = function () {
      img.src = '../DOM.html/IMG_3206.jpg';
    }
    tx2.onclick = function () {
      img.src = '../DOM.html/IMG_3204.jpg';
      img.title = "美女2";
    }

  </script>
</body>

在这里插入图片描述

<body>
    <!-- 根据系统不同时间来判断,所以需要用到日期的内置对象
    利用多分支语句来设置不同的图片
    需要一个图片,并且根据时间修改图片,就需要用到操作元素src属性
    需要一个div元素,显示不同问候语,修改元素内容即可 -->
    <img src="../image/bg1.png" alt="">
    <p>早上好</p>
    <script>
        // 1.获取元素
        var img = document.querySelector('img');
        var p = document.querySelector('p');
        // 2.得到当前的小时数
        var date = new Date();
        var h = date.getHours();
        // 3.判断小时数得到当前信息
        if (h < 12) {
            img.src = '../image/bg3.png'
            p.innerHTML = '亲,上午好';
        } else if (h < 18) {
            img.src = '../image/bg4.png'
            p.innerHTML = '亲,中午好';
        } else {
            img.src = '../image/bg5.png'
            p.innerHTML = '亲,晚上好';
        }


    </script>

3.修改表单元素

type、value、checked、selected、disabled
点击按钮,修改表单内容

<button>按钮</button>
    <input type="text" value="输入内容">
    <script>
        // 1.获取对象
        var bt = document.querySelector('button');
        var input = document.querySelector('input');
        // 2.注册事件
        bt.onclick = function () {
            input.value = "被点击了";
            // 如果想要某个表单被禁用 用disabled
            // 让button这个按钮被禁用
            bt.disabled = true;
        /* 或者用这句话 this指向的是bt*/  this.disabled = true;

        }
    </script>

在这里插入图片描述
在这里插入图片描述
点击密码框按钮,会切换密码显示、隐式

 <style>
        .box {
            position: relative;
            width: 400px;
            border-bottom: 1px solid #ccc;
            margin: 300px auto;

        }

        .box input {
            width: 370px;
            height: 30px;
            border: 0;
            outline: 0;
        }

        .box img {
            position: absolute;
            top: 2px;
            right: 2px;
            width: 24px;
        }
    </style>
</head>

<body>
    <div class="box">
        <label for="">
            <img src="../DOM.html/close.png" alt="" id="eye">
        </label>
        <input type="password" name="" id="pwd">
        <script>
            // 1.获取元素
            var eye = document.getElementById('eye');
            var pwd = document.getElementById('pwd');
            // 2.注册事件
            var flag = 0;
            eye.onclick = function () {
                // 点击一次之后flag发生了变化
                if (flag == 0) {
                    pwd.type = "text";
                    eye.scr = "../DOM.html/open.png";
                    flag = 1;
                } else {
                    pwd.type = "password";
                    eye.scr = "../DOM.html/close.png";
                    flag = 0;
                }


            }
        </script>

4.样式属性操作

可以通过JS修改元素的大小、颜色、位置等样式

element.style行内样式操作

element.className 类名样式操作

JS修改style样式操作,产生的是行内样式,CSS权重比较大
注意:
1.如果样式修改较多,可以采用操作类名方式更改元素样式
2.class因为是保留字,因此使用className来操作元素类名属性
3.className会直接更改元素的类名,会覆盖原先的类名

如果想要保留原先的类名可以:

this.className = 'first change';

淘宝点击关闭二维码案例:
当鼠标点击二维码关闭按钮的时候,则关闭整个二维码
在这里插入图片描述

<style>
    .box {
        position: relative;
        width: 74px;
        height: 88px;
        border: 1px solid #ccc;
        margin: 100px auto;
        font-size: 12px;
        text-align: center;
        color: #f40;
        /* display: block; */
    }
    
    .box img {
        width: 60px;
        margin-top: 5px;
    }
    
    .close-btn {
        position: absolute;
        top: -1px;
        left: -16px;
        width: 14px;
        height: 14px;
        border: 1px solid #ccc;
        line-height: 14px;
        font-family: Arial, Helvetica, sans-serif;
        cursor: pointer;
    }
</style>

</head>
<body>
    <div class="box">
        淘宝二维码
        <img src="../DOM.html/tao.png" alt="">
        <i class="close-btn">x</i>
        <script>
            // 1.获取元素
            var btn = document.querySelector('.close-btn');
            var box = document.querySelector('.box');
            // 2.注册事件
            btn.onclick = function(){
                box.style.display = 'none';
            }
        </script>
    </div>

效果图:点x隐藏,重新刷新再出现
在这里插入图片描述
显示隐藏文本框内容:
在这里插入图片描述

<input type="text" value="手机">
    <script>
        // 1.获取元素
        var text = document.querySelector('input');
        // 2.注册事件 获取焦点onfocus
        text.onfocus = function () {
            if (this.value == '手机') {
                this.value = '';
            }
            this.style.color = '#ccc';
        }

        text.onblur = function () {
            if (this.value == '') {
                this.value = "手机";
            }
            this.style.color = '#999';
        }
    </script>

效果图:
在这里插入图片描述
在这里插入图片描述
密码框格式提示错误信息案例:
用户如果离开密码框,里面输入个数不是6~16,则提示错误信息,否则提示输入正确信息
在这里插入图片描述

<style>
        div {
            width: 600px;
            margin: 100px auto;
        }

        .message {
            display: inline-block;
            font-size: 12px;
            color: #999;
            background: url(../DOM.html/mess.png) no-repeat left center;
            padding-left: 20px;
        }

        .wrong {
            color: red;
            background-image: url(../DOM.html/wrong.png);
        }

        .right {
            color: greenyellow;
            background-image: url(../DOM.html/right.png);
        }
    </style>

</head>

<body>
    <div class="register">
        <input type="password" class="ipt">
        <p class="message">请输入6~16为密码</p>
    </div>
    <script>
        // 首先判断的事件是表单失去焦点 onblur
        // 如果输入正确则提示正确的信息颜色为绿色小图标变化
        // 如果输入不是6到16位,则提示错误信息颜色为红色 小图标变化
        // 因为里面变化样式较多,我们采取className修改样式
        var ipt = document.querySelector('.ipt');
        var p = document.querySelector('.message');
        ipt.onblur = function () {
            if (this.value.length < 6 || this.value.length > 16) {
                p.className = 'message wrong';
                p.innerHTML = "您的位数不对";//修改p里面文本内容
            } else {
                p.className = 'message right';
                p.innerHTML = "您输入正确";
            }
        }

    </script>

效果图:
在这里插入图片描述
排他思想
在这里插入图片描述

 <button>按钮1</button>
    <button>按钮2</button>
    <button>按钮3</button>
    <button>按钮4</button>
    <button>按钮5</button>
    <script>
        // 1. 获取所有按钮元素
        var btn = document.getElementsByTagName('button');
        for (var i = 0; i < btn.length; i++) {
            btn[i].onclick = function () {
                for (var i = 0; i < btn.length; i++) {
                    btn[i].style.backgroundColor = '';
                }
                this.style.backgroundColor = 'pink';
            }

        }

    </script>

效果图:
在这里插入图片描述
更换背景图片:
在这里插入图片描述

 <style>
        * {
            margin: 0;
            padding: 0;
        }

        body {
            background: url(../DOM.html/4.jpg) no-repeat center top;
        }

        li {
            list-style: none;
        }

        .baidu {
            overflow: hidden;
            margin: 100px auto;
            background-color: #fff;
            width: 410px;
            padding-top: 3px;
        }

        .baidu li {
            float: left;
            margin: 0 1px;
            cursor: pointer;
        }

        .baidu img {
            width: 100px;
        }
    </style>
</head>

<body style="background-image: url(../DOM.html/4.jpg);">
    <ul class="baidu">
        <li><img src="../DOM.html/1.jpg" alt=""></li>
        <li><img src="../DOM.html/2.jpg" alt=""></li>
        <li><img src="../DOM.html/3.jpg" alt=""></li>
        <li><img src="../DOM.html/4.jpg" alt=""></li>
    </ul>
    <script>
        var img = document.querySelectorAll('img');
        for (var i = 0; i < img.length; i++) {
            img[i].onclick = function () {
                document.body.style.backgroundImage = 'url(' + this.src + ')'
            }
        }
    </script>

效果图:
在这里插入图片描述
表格隔行变色效果:

<style>
        table {
            width: 800px;
            margin: 100px auto;
            text-align: center;
            border-collapse: collapse;
            font-size: 14;
        }

        thead tr {
            height: 30px;
            background-color: skyblue;
        }

        tbody tr {
            border-bottom: 1px solid #d7d7d7;
            height: 30px;
        }

        tbody td {
            color: blue;
            font-size: 12px;
        }

        .bg {
            background-color: pink;
        }
    </style>
</head>

<body>
    <table>
        <thead>
            <tr>
                <th>代码</th>
                <th>名称</th>
                <th>最新公布净值</th>
                <th>累计净值</th>
                <th>前单位净值</th>
                <th>净值增长率</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>003526</td>
                <td>农银金穗3个月定期开放债券</td>
                <td>1.075</td>
                <td>1.079</td>
                <td>1.074</td>
                <td>+0.047%</td>
            </tr>
            <tr>
                <td>003526</td>
                <td>农银金穗3个月定期开放债券</td>
                <td>1.075</td>
                <td>1.079</td>
                <td>1.074</td>
                <td>+0.047%</td>
            </tr>
            <tr>
                <td>003526</td>
                <td>农银金穗3个月定期开放债券</td>
                <td>1.075</td>
                <td>1.079</td>
                <td>1.074</td>
                <td>+0.047%</td>
            </tr>
            <tr>
                <td>003526</td>
                <td>农银金穗3个月定期开放债券</td>
                <td>1.075</td>
                <td>1.079</td>
                <td>1.074</td>
                <td>+0.047%</td>
            </tr>
            <tr>
                <td>003526</td>
                <td>农银金穗3个月定期开放债券</td>
                <td>1.075</td>
                <td>1.079</td>
                <td>1.074</td>
                <td>+0.047%</td>
            </tr>
            <tr>
                <td>003526</td>
                <td>农银金穗3个月定期开放债券</td>
                <td>1.075</td>
                <td>1.079</td>
                <td>1.074</td>
                <td>+0.047%</td>
            </tr>
        </tbody>
    </table>
    <script>
        var trs = document.querySelector('tbody').querySelectorAll('tr');
        for (var i = 0; i < trs.length; i++) {
            trs[i].onmouseover = function () {
                this.className = 'bg';
            }
            trs[i].onmouseout = function () {
                this.className = '';
            }
        }
    </script>

核心点:

trs[i].onmouseover = function () { // 鼠标经过事件onmouseover
this.className = ‘bg’;
}
trs[i].onmouseout = function () { //鼠标离开事件onmouseout
this.className = ‘’;
}

效果图:
在这里插入图片描述
表单全选取消全选:
在这里插入图片描述

<style>
        * {
            padding: 0;
            margin: 0;
        }

        .wrap {
            width: 300px;
            margin: 100px auto;
        }

        table {
            width: 400px;
            margin: 100px auto;
            text-align: center;
            border-spacing: 0;
            border: 1px solid #c0c0c0;
            border-collapse: collapse;
        }

        th,
        td {
            border: solid 1px #d0d0d0;
            color: #404060;
            padding: 10px;
        }

        th {
            background-color: #09c;
            font: bold 16px "微软雅黑";
            color: #fff;
        }

        tbody tr {
            background-color: #f0f0f0;
        }

        tbody tr:hover {
            cursor: pointer;
            background-color: #fafafa;
        }
    </style>
</head>

<body>
    <div class="wrap">
        <table>
            <thead>
                <tr>
                    <th><input type="checkbox" id="j_cbA11"></th>
                    <th>商品</th>
                    <th>价钱</th>
                </tr>
            <tbody id="j_tb">
                <tr>
                    <td><input type="checkbox"></td>
                    <td>iphone8</td>
                    <td>8000</td>
                </tr>
                <tr>
                    <td><input type="checkbox"></td>
                    <td>iphone8</td>
                    <td>8000</td>
                </tr>
                <tr>
                    <td><input type="checkbox"></td>
                    <td>iphone8</td>
                    <td>8000</td>
                </tr>
                <tr>
                    <td><input type="checkbox"></td>
                    <td>iphone8</td>
                    <td>8000</td>
                </tr>
            </tbody>
            </thead>
        </table>
    </div>
    <script>
        var j_cbA11 = document.getElementById('j_cbA11');//全选按钮
        var j_tb = document.getElementById('j_tb').getElementsByTagName('input');//下面所有的复选框
        j_cbA11.onclick = function () {
            for (var i = 0; i < j_tb.length; i++) {
                //this.checked 它可以得到当前复选框的选中状态如果是true就是选中 如果是false就是未选中
                j_tb[i].checked = this.checked;
            }
        }
    </script>
</body>

核心点:

j_tb[i].checked = this.checked;

效果图:
在这里插入图片描述
如果下面的小按钮全选上上面的按钮自动选上

 // 2.下面复选框需要全部选中,上面全选才能选中的做法:
        for (var i = 0; i < j_tb.length; i++) {
            j_tb[i].onclick = function () {
 //控制全选按钮是否被选中
                var flag = true;
 //每次点击下面的复选框都要循环检查这4个小按钮是否被全选中
                for (var i = 0; i < j_tb.length; i++) {
                    if (!j_tb[i].checked) {
                        flag = false;
                    }
                }
                j_cbA11.checked = flag;
            }
        }

5.自定义属性操作

(1)获取属性值

  • element.属性 获取属性值
  • element.getAttribute(‘属性’);

区别:
element.属性 获取属性值 是获取内置属性值(元素本身自带的属性)
element.getAttribute(‘属性’); 主要获取自定义的属性(标准)我们程序员自定义的属性

<div id="demo"></div>
    <script>
        var div = document.querySelector('div');
        // 1.获取元素的属性值
        // (1)element.属性
        console.log(div.id);//demo
        // (2)element.getAttribute('属性');
        console.log(div.getAttribute('id'));
    </script>

(2)设置自定义属性

  • element.属性=‘值’ 设置内置属性值
  • element.setAttribute(‘属性’,‘值’); 第一个参数需要改哪个属性,第二个参数需要改哪个值
  • removeAttribute(‘属性’) 移除属性
<div id="demo" index="1"></div>
// 2.设置元素属性值
        // (1)element.属性='值';
        div.id = 'test';
        // element.setAttribute('属性','值');主要针对于自定义属性
        div.setAttribute('index', 2);

tab栏切换制作:
在这里插入图片描述

<style>
        * {
            margin: 0;
            padding: 0;
        }

        li {
            list-style-type: none;
        }

        .tab {
            width: 978px;
            margin: 100px auto;
        }

        .tab_list {
            height: 39px;
            border: 1px solid #ccc;
            background-color: #f1f1f1;
        }

        .tab_list li {
            float: left;
            height: 39px;
            line-height: 39px;
            padding: 0 20px;
            text-align: center;
            cursor: pointer;
        }

        .tab_list .current {
            background-color: #c81623;
            color: #fff;
        }

        .item_info {
            padding: 20px 0 0 20px;
        }

        .item {
            display: none;
        }
    </style>

</head>

<body>
    <div class="tab">
        <div class="tab_list">
            <ul>
                <li class="current">商品介绍</li>
                <li>规格与包装</li>
                <li>售后保障</li>
                <li>商品评价</li>
                <li>手机社区</li>
            </ul>
        </div>
        <div class="tab_con">
            <div class="item">商品介绍模块内容</div>
            <div class="item">规格与包装模块内容</div>
            <div class="item">售后保障模块内容</div>
            <div class="item">商品评价模块内容</div>
            <div class="item">手机社区模块内容</div>
        </div>
    </div>
    <script>
        // 1.上面的模块选项卡,点击某一个,当前这个模块的底色会是红色,其余不变(排他思想) 修改类名的方式
        // 获取元素
        var tabs = document.getElementsByTagName('li');//获取当前标签对象的集合
        var item = document.querySelectorAll('.item'); // 获取下面模块指定类的集合
        for (var i = 0; i < tabs.length; i++) {  //循环遍历li
            //开始给5个li设置索引号
            tabs[i].setAttribute('index', i);  // 对每一个li设置自定义属性


            tabs[i].onclick = function () {     //当点击其中一个li
                for (var i = 0; i < tabs.length; i++) {  //再次循环遍历 排他思想
                    tabs[i].className = '';//先去掉每一个li的颜色
                }
                this.className = 'current';  //载把当前指向的Li设置cunrrent类里面的属性


                // 2.下面的显示模块
                var index = this.getAttribute('index');  //获取自定义属性值
                for (var i = 0; i < item.length; i++) {  //对下面模块div循环遍历 排他思想
                    item[i].style.display = 'none';  //所有模块的内容隐藏
                }
                item[index].style.display = 'block'; //对应点击的模块内容显示
            }
        }
    </script>

效果图:
在这里插入图片描述

(3)H5自定义属性

自定义属性目的:是为了保存并使用数据。有些数据可以保存到页面中而不用保存到数据库中
自定义属性data-开头作为属性名并且赋值
比如:<div data-index = "1"></div>在这里插入图片描述

五、节点操作

为什么要写节点操作:DOM获取元素太繁琐,我们可以用节点层次关系获取
一般地,节点至少拥有nodeType(节点类型)、nodeName(节点名称)、nodeValue(节点值)这三个基本属性:

  • 元素节点 nodeType 为1
  • 属性节点 nodeType 为2
  • 文本节点 nodeType 为3(文本节点包含文字、空格、换行等)

我们在实际开发中主要操作的是元素节点

1.节点层级

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

(1)父级节点

node.parentNode
parentNode属性可返回某节点的父节点,注意是最近的节点
如果指定的节点没有父节点则返回Null

(2)子节点

1.parentNode.childNodes(标准)
返回包含指定节点的子节点的集合,该集合为即时更新的集合
注意: 返回值里面包含了所有的子节点,包括元素节点,文本节点等
如果只想要获得里面的元素节点,则需要专门处理,所以我们一般不提倡使用childNodes
parentNode.children(非标准)
parentNode.children是一个只读属性,返回所有的子元素节点。它只返回子元素节点,其余节点不返回(这个是我们重点掌握的)

2.parentNode.firstChild返回第一个子节点,找不到则返回null。同样也是包含所有的节点
parentNode.lastChild返回最后一个子节点,找不到则返回null。同样也是包含所有的节点

3.实际开发中最常用,既没有兼容性问题又可以返回第一个子元素
parentNode.Children注意无参数
在这里插入图片描述
新浪下拉菜单:
在这里插入图片描述

 <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>
                    <a href>评论</a>
                    <a href>@我</a>
                </li>
            </ul>
        </li>
        <li>
            <a href="#">微博</a>
            <ul>
                <li><a href>私信</a>
                    <a href>评论</a>
                    <a href>@我</a>
                </li>
            </ul>
        </li>
        <li>
            <a href="#">微博</a>
            <ul>
                <li><a href>私信</a>
                    <a href>评论</a>
                    <a href>@我</a>
                </li>
            </ul>
        </li>
        <li>
            <a href="#">微博</a>
            <ul>
                <li><a href>私信</a>
                    <a href>评论</a>
                    <a href>@我</a>
                </li>
            </ul>
        </li>
    </ul>
    <script>
        // 1.获取元素
        var nav = document.querySelector('.nav'); //获取ul这一大块里面元素
        var lis = nav.children;  //获取nav里面的4个小li
        for (var i = 0; i < lis.length; i++) {//遍历循环4个li
            lis[i].onmouseover = function () {//鼠标经过触发
                this.children[1].style.display = 'block';//4个li中点击的那个的第二个模块显示出来
            }
            lis[i].onmouseout = function () {//鼠标离开触发
                this.children[1].style.display = 'none';//4个li中点击的那个的第二个模块隐藏
            }
        }
    </script>

效果图:
在这里插入图片描述

(3)兄弟节点

1.node.nextSibling返回当前元素的下一个兄弟节点找不到则返回Null 同样也是包含所有的节点
node.previousSibling返回当前元素的上一个兄弟节点找不到则返回Null 同样也是包含所有的节点
2.node.nextElementSibling返回当前元素的下一个兄弟元素节点找不到则返回Null
node.previousElementSibling返回当前元素的上一个兄弟元素节点找不到则返回Null
注意这两个方法有兼容性问题
在这里插入图片描述

2.页面中添加新元素

创建节点:
document.createElement('tagName')
方法创建由tagName指定的HTML元素,因为这些元素原先不存在。是根据我们的动态生成的,所以我们也称为动态创建元素节点
添加节点:
node.appendChild(child)
方法将一个节点添加到指定父节点的子节点列表末尾 类似于CSS里面的after伪元素
node.insertBefore('child,指定元素')
方法将一个节点添加到父节点的指定子节点前面似于CSS里面的before伪元素
在这里插入图片描述
先创建li 再将li放到ul里

 // (1)创建元素
         var li = document.createElement('li');
 // (2)添加元素
        ul.appendChild(li);

简单版发布留言案例:
在这里插入图片描述

 <style>
        * {
            margin: 0;
            padding: 0;
        }

        body {
            padding: 100px;
        }

        textarea {
            width: 200px;
            height: 100px;
            border: 1px solid pink;
            outline: none;
            resize: none;
        }

        ul {
            margin-top: 50px;
        }

        li {
            width: 300px;
            padding: 5px;
            background-color: rgb(245, 209, 243);
            color: red;
            font-size: 14px;
            margin: 15px 0;
        }
    </style>
</head>

<body>
    <textarea name="" id="" cols="30" rows="10">123</textarea>
    <button>发布</button>
    <ul> </ul>
    <script>
        var text = document.querySelector('textarea');
        var btn = document.querySelector('button');
        var ul = document.querySelector('ul');
        btn.onclick = function () {  //点击button按钮创建元素
            // (1)创建元素
            var li = document.createElement('li');
            li.innerHTML = text.value;  // 将textarea里面的值放到li里
            // (2)添加元素
            ul.insertBefore(li, ul.children[0]);//将li 放到ul孩子的第一个

        }


    </script>

效果图:
在这里插入图片描述

3.页面中删除节点

node.removeChild(child)
方法从DOM中删除一个子节点,返回删除的节点
在这里插入图片描述
删除留言案例:
在这里插入图片描述

 li.innerHTML = text.value + "<a href='javascript:;'>删除</a>";  // 将textarea里面的值放到li里
            // (2)添加元素
            ul.insertBefore(li, ul.children[0]);//将li 放到ul孩子的第一个
            // 删除元素删除当前元素的li
            var as = document.querySelectorAll('a');//获得所有a
            for(var i = 0; i < as.length; i++){ //循环遍历a
                as[i].onclick = function(){  //当点击某一个a时
                    ul.removeChild(this.parentNode);  //删除a所在的li
                }
            }

效果图:
在这里插入图片描述

4.复制节点

node.cloneNode()
方法返回调用该方法的节点的一个副本。也称为克隆节点/拷贝节点
在这里插入图片描述
动态生成表格:

 <style>
        * {
            margin: 0;
            padding: 0;
        }

        table {
            width: 400px;
            margin: 100px auto;
            border-collapse: collapse;
            border: 1px solid black;
        }

        tr th {
            height: 25px;
            background-color: #ccc;
            font: 14px;
            border: 1px solid black;
        }

        td {
            border: 1px solid black;

        }
    </style>
</head>

<body>
    <table>

        <thead>
            <tr>
                <th>名字</th>
                <th>学科</th>
                <th>得分</th>
                <th>删除</th>
            </tr>
        </thead>
        <tbody>

        </tbody>
    </table>
    <script>
 // 1.创建对象 将对象创建成数组的形式
        var data = [{
            name: '楠楠',
            subject: 'java',
            score: 99,
        },
        {
            name: '洋洋',
            subject: 'java',
            score: 99,
        },
        {
            name: '丽丽',
            subject: 'java',
            score: 99,
        }]
// 2.往tbody里面创建行,有多少属性创建多少行
        var tbody = document.querySelector('tbody');   //获取tbody
        for (var i = 0; i < data.length; i++) {    //整个for为了创建单元格
            var tr = document.createElement('tr');   //创建单元行
            tbody.appendChild(tr);    //在tbody里添加行节点
// 行里面创建单元格 单元格的数量取决于对象里面属性数量 用for循环遍历
            for (var k in data[i]) { //遍历对象用var k in obj 来遍历
                var td = document.createElement('td');
                td.innerHTML = data[i][k];
                tr.appendChild(td);
            }
// 创建有删除2个字的单元格
            var td = document.createElement('td');
            td.innerHTML = " <a href='javascript:;'>删除</a>";
            tr.appendChild(td);
        }
// 删除操作:
        var as = document.querySelectorAll('a');
        for (var i = 0; i < as.length; i++) {
            as[i].onclick = function () {
                tbody.removeChild(this.parentNode.parentNode);
            }
        }
    </script>
</body>

5.三种动态创建元素区别

document.write( )
element.innerHTML
document.createElement( )
区别:1.document.write( )是直接将内容写入页面的内容流,但是文档流执行完毕则它会导致页面全部重绘

六.DOM重点核心

关于DOM操作,我们主要针对于元素的操作。主要创建、增删改查、属性操作、事件操作
创建元素三种方法:
document.write( )
element.innerHTML
document.createElement( )
:添加新的元素:
node.insertBefore('child,指定元素')
node.appendChild(child)
:删除元素:
node.removeChild(child)
:主要修改DOM的元素属性,DOM元素的内容、属性、表单的值等
1.修改元素属性:src、href、title等
2.修改普通元素内容:innerHTML 、innerText
3.修改表单元素:value、type、disabled等
4.修改元素样式:style、className
查:主要查询DOM元素
在这里插入图片描述
属性操作:主要针对自定义属性
setAttribute: 设置dom的属性值
getAttribute: 得到dom的属性值
removeAttribute:移除属性
事件操作:给元素注册事件,采取,事件源,事件类型=事件处理程序
在这里插入图片描述

1.注册事件

给元素添加事件,称为注册事件或者绑定事件
注册事件有两种方式:传统方式和方法监听注册方式

传统注册方式:
在这里插入图片描述
方法监听注册方式:
在这里插入图片描述
addEventListener事件监听方式
eventTarget.addEventListener(type, listener[ , useCapture])
eventTarget.addEventListener( )方法将指定的监听器注册到eventTarget(目标对象)上,当该对象触发指定事件时,就会执行事件处理函数
该方法接收三个参数:

  • type:事件类型字符串,比如:click、mouseover、注意这里不要带on
  • listener:事件处理函数,事件发生时,会调用该监听函数
  • useCapture:可选参数,是一个布尔值,默认是false
    在这里插入图片描述

2.删除事件(解绑事件)

1.传统注册方式:
eventTarget.onclick = null;
在这里插入图片描述
2.方法监听注册方式:
eventTarget.removeEventListener(type, listener[ , useCapture])
eventTarget.detachEvent(eventNameWithOn,callback);
在这里插入图片描述

3.DOM事件流

事件流描述的是从页面中接收事件的顺序
事件发生时会在元素节点之间按照特定的顺序传播,这个传播过程即DOM事件流
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

4.事件对象

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
事件对象常用属性和方法:
在这里插入图片描述
在这里插入图片描述
this和e.target区别:
this绑定谁就返回谁
e.target点击谁返回谁

 <div>123</div>
   <script>
       var div = document.querySelector('div');
       div.addEventListener('click',fn);
       function fn(e){
        // 返回触发事件对象
        console.log(e.target);//返回触发事件对象<div>123</div>
        // 返回事件类型
        console.log(e.type);//返回事件的类型 click
       }

阻止事件冒泡:
事件冒泡:开始时由最具体的元素接收,然后逐级向上传播到DOM最顶层节点
事件冒泡本身的特性,会带来的坏处,也会带来的好处,需要我们灵活掌握
事件委托:
在这里插入图片描述
事件委托原理:
不是每个子节点单独设置事件监听器。而是事件监听器设置在其父节点上,然后利用冒泡原理影响设置每个子节点
例如:给ul注册点击事件,然后利用事件对象的target来找到当前点击的li,因为点击li,事件会冒泡到ul上,ul有注册事件,就会触发事件监听器。
事件委托的作用:
我们只操作了一次DOM,提高了程序的性能
在这里插入图片描述
常用的鼠标事件:
在这里插入图片描述
在这里插入图片描述
鼠标事件对象:
event对象代表事件的状态,跟事件相关的一系列信息集合。现阶段我们主要是用鼠标事件对象MouseEvent和键盘事件对象KeyboardEvent
在这里插入图片描述
跟随鼠标天使案例:

 <img src="../DOM.html/angel.gif" alt="">
    <script>
        var img = document.querySelector('img');
        // 我们只要移动鼠标px 就会触发事件
        document.addEventListener('mousemove',function(e){
            // 核心原理:每次鼠标移动,我们都会获得最新鼠标坐标,把x和y坐标作为图片的top和left值就可以移动图片
            var x = e.pageX;
            var y = e.pageY;
            // 千万不要忘记给left和top加px单位
            img.style.left = x + 'px';
            img.style.top = y - 50 + 'px';
        })
    </script>

效果图:鼠标移动到哪图片跟随到哪
在这里插入图片描述
常用的键盘触发:
在这里插入图片描述
模拟京东按键输入内容案例:
在这里插入图片描述

<input type="text">
   <script>
       var search = document.querySelector('input');
       document.addEventListener('keyup',function(e){
           if(e.keyCode === 83){
            search.focus();
           }
       })
   </script>

按下s键,获取搜索框焦点
模拟京东快递单号查询:
在这里插入图片描述
在这里插入图片描述在这里插入图片描述

 <style>
        * {
            margin: 0;
            padding: 0;
        }

        .search {
            position: relative;
            width: 178px;
            margin: 100px;
        }

        .con {
            display: none;
            position: absolute;
            top: -40px;
            width: 171px;
            border: 1px solid rgba(0, 0, 0, .2);
            box-shadow: 0 2px 4px rgba(0, 0, 0, .2);
            padding: 5px 0;
            font-size: 18px;
            line-height: 20px;
            color: #333;
        }

        .con::before {
            content: '';
            width: 0;
            height: 0;
            position: absolute;
            top: 28px;
            left: 18px;
            border: 8px solid #000;
            border-style: solid dashed dashed;
            border-color: #fff transparent transparent;
        }
    </style>
</head>

<body>
    <div class="search">
        <div class="con"></div>
        <input type="text" placeholder="请输入您的快递单号" class="jd">
    </div>
    <script>

        // 快递单号输入内容时, 上面的大号字体盒子(con)显示(这里面的字号更大)
        // 表单检测用户输入: 给表单添加键盘事件
        // 同时把快递单号里面的值(value)获取过来赋值给 con盒子(innerText)做为内容
        // 如果快递单号里面内容为空,则隐藏大号字体盒子(con)盒子
        var con = document.querySelector('.con');
        var jd_input = document.querySelector('.jd');
        jd_input.addEventListener('keyup', function () {
            // console.log('输入内容啦');
            if (this.value == '') {
                con.style.display = 'none';
            } else {
                con.style.display = 'block';
                con.innerText = this.value;
            }
        })
        // 当我们失去焦点,就隐藏这个con盒子
        jd_input.addEventListener('blur', function () {
            con.style.display = 'none';
        })
        // 当我们获得焦点,就显示这个con盒子
        jd_input.addEventListener('focus', function () {
            if (this.value !== '') {
                con.style.display = 'block';
            }
        })

    </script>
</body>

效果图:
在这里插入图片描述

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值