Web APls 阶段——第十一节(1)——节点操作,时间对象,重绘和回流

本文深入探讨了JavaScript中的DOM节点操作,包括节点类型、层级、查找、增加、删除等,并通过实际案例展示了如何实现关闭二维码、微博下拉菜单等功能。此外,还介绍了时间对象的创建、常用方法及时间戳的应用,如页面实时时间显示和毕业倒计时效果。文章最后提及了浏览器的重绘和回流概念,帮助理解页面渲染过程。
摘要由CSDN通过智能技术生成

目标:

  1. 掌握节点(标签)的增删改查
  2. 具备编写微博发布案例的能力

1. 节点操作

1.1 DOM 节点

  • 目标:能说出DOM节点的类型
    在这里插入图片描述
    在这里插入图片描述

  • DOM节点:DOM树里每一个内容都称之为节点。

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

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

  • 一般地,节点至少拥有nodeType(节点类型)、nodeName(节点名称)和nodeValue(节点值)这三个基本属性。在这里插入图片描述

1.1.1 节点类型:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

1.1.2 节点层级

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

1.2 查找节点

目标:能够具备根据节点关系查找目标节点的能力

关闭二维码案例:

点击关闭按钮, 关闭的是二维码的盒子, 还要获取erweima盒子
在这里插入图片描述
在这里插入图片描述

1.2.1 父节点查找

  • parentNode 属性
  • 返回最近一级的父节点 ,找不到返回为null
    在这里插入图片描述
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div class="father">
        <div class="son">儿子</div>
    </div>
    <script>
        let son = document.querySelector('.son')
        // 找爸爸
        console.log(son.parentNode)
        
    </script>
</body>

</html>

在这里插入图片描述

案例:关闭二维码案例
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        .erweima {
            position: relative;
            width: 160px;
            height: 160px;
            margin: 100px auto;
            border: 1px solid #ccc;
        }

        .erweima i {
            position: absolute;
            left: -13px;
            top: 0;
            width: 10px;
            height: 10px;
            border: 1px solid #ccc;
            font-size: 12px;
            line-height: 10px;
            color: #ccc;
            font-style: normal;
            cursor: pointer;
        }
    </style>
</head>

<body>
    <div class="erweima">
        <img src="./images/code.png" alt="">
        <i class="close_btn">x</i>
    </div>
    <script>
        // 1. 获取元素   事件源 i   关闭的 erweima 
        let close_btn = document.querySelector('.close_btn')
        let erweima = document.querySelector('.erweima')
        // 2. 事件监听
        close_btn.addEventListener('click', function () {
            // erweima 关闭  他是隐藏的
            erweima.style.display = 'none'
        })
    </script>
</body>

</html>
案例:关闭多个二维码案例

需求:多个二维码,点击谁,谁关闭

分析:
①:需要给多个按钮绑定点击事件
②:关闭的是当前的父节点

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Document</title>
  <style>
    .erweima {
      width: 149px;
      height: 152px;
      border: 1px solid #000;
      background: url(./images/456.png) no-repeat;
      position: relative;
    }

    .close {
      position: absolute;
      right: -52px;
      top: -1px;
      width: 50px;
      height: 50px;
      background: url(./images/bgs.png) no-repeat -159px -102px;
      cursor: pointer;
      border: 1px solid #000;

    }
  </style>
</head>

<body>
  <div class="erweima">
    <span class="close"></span>
  </div>
  <div class="erweima">
    <span class="close"></span>
  </div>
  <div class="erweima">
    <span class="close"></span>
  </div>
  <div class="erweima">
    <span class="close"></span>
  </div>
  <div class="erweima">
    <span class="close"></span>
  </div>

  <script>
    // 1. 获取元素  关闭按钮
    let close_btn = document.querySelectorAll('.close')
    // 2. 绑定多个点击事件给close
    for (let i = 0; i < close_btn.length; i++) {
      close_btn[i].addEventListener('click', function () {
        // 3. 关闭当前的那个二维码  点击谁,就关闭谁的爸爸
        this.parentNode.style.visibility = 'hidden'
      })
    }
  </script>
</body>

</html>

1.2.2 子节点查找

在这里插入图片描述

1.2.3 案例:新浪下拉菜单

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <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');
        var lis = nav.children; // 得到4个小li
        // 2.循环注册事件
        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>

</html>

1.2.4 兄弟关系查找

在这里插入图片描述
在这里插入图片描述

1.3 增加节点

目标:能够具备根据需求新增节点的能力

在这里插入图片描述
在这里插入图片描述

1.3.1 创建节点

  • 即创造出一个新的网页元素,再添加到网页内,一般先创建节点,然后插入节点
  • 创建元素节点方法:
    在这里插入图片描述

1.3.2 追加节点

  • 要想在界面看到,还得插入到某个父元素中
  • 插入到父元素的最后一个子元素:
    在这里插入图片描述
  • 插入到父元素中某个子元素的前面
    在这里插入图片描述
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <ul>
        <li>我是大毛</li>
        <li>我是二毛</li>
    </ul>
    <script>
        // 二毛   ul.children[1]
        // 1. 创建新的标签节点
        // let div = document.createElement('div')
        // div.className = 'current'
        let ul = document.querySelector('ul')
        let li = document.createElement('li')

        li.innerHTML = '我是xiao ming'
        // 2. 追加节点  父元素.appendChild(子元素) 后面追加
        // ul.appendChild(li)
        // 3. 追加节点  父元素.insertBefore(子元素, 放到那个元素的前面)   
        ul.insertBefore(li, ul.children[0])
    </script>
</body>

</html>
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>
    <ul>
        <li>123</li>
    </ul>
    <script>
        // 1. 创建节点元素节点
        var li = document.createElement('li');
        // 2. 添加节点 node.appendChild(child)  node 父级  child 是子级 后面追加元素  类似于数组中的push
        var ul = document.querySelector('ul');
        ul.appendChild(li);
        // 3. 添加节点 node.insertBefore(child, 指定元素);
        var lili = document.createElement('li');
        ul.insertBefore(lili, ul.children[0]);
        // 4. 我们想要页面添加一个新的元素 : 1. 创建元素 2. 添加元素
    </script>
</body>

</html>

1.3.3 案例:学成在线案例渲染

需求:按照数据渲染页面
在这里插入图片描述

分析:

①:准备好空的ul 结构
②:根据数据的个数,创建一个新的空li
③:li里面添加内容 img 标题等
④:追加给ul

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>学车在线首页</title>
    <link rel="stylesheet" href="style.css">

</head>

<body>

    <!-- 4. box核心内容区域开始 -->
    <div class="box w">
        <div class="box-hd">
            <h3>精品推荐</h3>
            <a href="#">查看全部</a>
        </div>
        <div class="box-bd">
            <ul class="clearfix">
                <!-- <li>
                    <img src="./images/course01.png" alt="">
                    <h4>
                        Think PHP 5.0 博客系统实战项目演练
                    </h4>
                    <div class="info">
                        <span>高级</span> • <span> 1125</span>人在学习
                    </div>
                </li> -->
            </ul>
        </div>
    </div>
    <script>
        let data = [
            {
                src: 'images/course01.png',
                title: 'Think PHP 5.0 博客系统实战项目演练',
                num: 1125
            },
            {
                src: 'images/course02.png',
                title: 'Android 网络动态图片加载实战',
                num: 357
            },
            {
                src: 'images/course03.png',
                title: 'Angular2 大前端商城实战项目演练',
                num: 22250
            },
            {
                src: 'images/course04.png',
                title: 'Android APP 实战项目演练',
                num: 389
            },
            {
                src: 'images/course05.png',
                title: 'UGUI 源码深度分析案例',
                num: 124
            },
            {
                src: 'images/course06.png',
                title: 'Kami2首页界面切换效果实战演练',
                num: 432
            },
            {
                src: 'images/course07.png',
                title: 'UNITY 从入门到精通实战案例',
                num: 888
            },
            {
                src: 'images/course08.png',
                title: '我会变,你呢?',
                num: 590
            },
            {
                src: 'images/course08.png',
                title: '我会变,你呢?',
                num: 590
            }
        ]
        let ul = document.querySelector('ul')
        // 1. 根据数据的个数,决定这小li的个数
        for (let i = 0; i < data.length; i++) {
            // 2. 创建小li
            let li = document.createElement('li')
            // console.log(li)

            // 4. 先准备好内容,再追加 
            li.innerHTML = `
            <img src=${data[i].src} alt="">
            <h4>
                ${data[i].title}
            </h4>
            <div class="info">
                <span>高级</span> • <span> ${data[i].num}</span>人在学习
            </div>
            `
            // 3. 追加给ul   父元素.appendChild(子元素)
            ul.appendChild(li)

        }
    </script>
</body>

</html>

1.3.4 (复制节点)克隆节点

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
注意∶
1.如果括号参数为空或者为false,则是浅拷贝,即只克隆复制节点本身,不克隆里面的子节点。
⒉如果括号参数为true,则是深度拷贝,会复制节点本身以及里面所有的子节点。

1.4 删除节点 :node.removeChild(child)

在这里插入图片描述
注:

  • 如不存在父子关系,则删除不成功
  • 删除节点和隐藏节点(display:none) 有区别的: 隐藏节点还是存在的,但是删除,则从html中删除节点

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>
    <button>删除</button>
    <ul>
        <li>熊大</li>
        <li>熊二</li>
        <li>光头强</li>
    </ul>
    <script>
        // 1.获取元素
        var ul = document.querySelector('ul');
        var btn = document.querySelector('button');
        // 2. 删除元素  node.removeChild(child)
        // ul.removeChild(ul.children[0]);
        // 3. 点击按钮依次删除里面的孩子
        btn.onclick = function() {
            if (ul.children.length == 0) {
                this.disabled = true;
            } else {
                ul.removeChild(ul.children[0]);
            }
        }
    </script>
</body>

</html>

2. 时间对象

  • 目标:能够实例化时间对象
  • 时间对象:用来表示时间的对象
  • 作用:可以得到当前系统时间
    在这里插入图片描述
    在这里插入图片描述

2.1 实例化

  • 在代码中发现了 new 关键字时,一般将这个操作称为实例化
  • 创建一个时间对象并获取时间

在这里插入图片描述

2.2 时间对象方法

目标:能够使用时间对象中的方法写出常见日期

  • 因为时间对象返回的数据我们不能直接使用,所以需要转换为实际开发中常用的格式
    在这里插入图片描述

2.3 案例:页面显示时间

需求:将当前时间以:YYYY-MM-DD HH:mm 形式显示在页面
案例
分析:
①:调用时间对象方法进行转换
②:字符串拼接后,通过 innerText 给 标签

2.4 时间戳

目标:能够获得当前时间戳
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.5 案例:毕业倒计时效果

需求:计算到下课还有多少时间
在这里插入图片描述

分析:
①:用将来时间减去现在时间就是剩余的时间
②:核心: 使用将来的时间戳减去现在的时间戳
③:把剩余的时间转换为 天 时 分 秒

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Document</title>
  <style>
    .countdown {
      width: 240px;
      height: 305px;
      text-align: center;
      line-height: 1;
      color: #fff;
      background-color: brown;
      /* background-size: 240px; */
      /* float: left; */
      overflow: hidden;
    }

    .countdown .next {
      font-size: 16px;
      margin: 25px 0 14px;
    }

    .countdown .title {
      font-size: 33px;
    }

    .countdown .tips {
      margin-top: 80px;
      font-size: 23px;
    }

    .countdown small {
      font-size: 17px;
    }

    .countdown .clock {
      width: 142px;
      margin: 18px auto 0;
      overflow: hidden;
    }

    .countdown .clock span,
    .countdown .clock i {
      display: block;
      text-align: center;
      line-height: 34px;
      font-size: 23px;
      float: left;
    }

    .countdown .clock span {
      width: 34px;
      height: 34px;
      border-radius: 2px;
      background-color: #303430;
    }

    .countdown .clock i {
      width: 20px;
      font-style: normal;
    }
  </style>
</head>

<body>
  <div class="countdown">
    <p class="next">今天是2021年8月28日</p>
    <p class="title">下班倒计时</p>
    <p class="clock">
      <span id="hour">00</span>
      <i>:</i>
      <span id="minutes">25</span>
      <i>:</i>
      <span id="scond">20</span>
    </p>
    <p class="tips">
      现在是18:30:00
    </p>
  </div>
  <script>
    let hour = document.querySelector('#hour')
    let minutes = document.querySelector('#minutes')
    let scond = document.querySelector('#scond')
    time()
    setInterval(time, 1000)
    function time() {
      // 1. 得到现在的时间戳
      let now = +new Date()
      // 2. 得到指定时间的时间戳
      let last = +new Date('2021-8-29 18:30:00')
      // 3. (计算剩余的毫秒数) / 1000 === 剩余的秒数
      let count = (last - now) / 1000
      // console.log(count)
      // 4. 转换为时分秒
      // h = parseInt(总秒数 / 60 / 60 % 24)   //   计算小时
      let h = parseInt(count / 60 / 60 % 24)
      h = h < 10 ? '0' + h : h
      // m = parseInt(总秒数 / 60 % 60);     //   计算分数
      let m = parseInt(count / 60 % 60)
      m = m < 10 ? '0' + m : m
      // s = parseInt(总秒数 % 60); //   计算当前秒数
      let s = parseInt(count % 60);
      s = s < 10 ? '0' + s : s
      // console.log(h, m, s)
      hour.innerHTML = h
      minutes.innerHTML = m
      scond.innerHTML = s
    }

  </script>
</body>

</html>

在这里插入图片描述
在这里插入图片描述

3 .重绘和回流

3.1 浏览器是如何进行界面渲染的

在这里插入图片描述

  • 解析(Parser)HTML,生成DOM树(DOM Tree)
  • 同时解析(Parser) CSS,生成样式规则 (Style Rules)
  • 根据DOM树和样式规则,生成渲染树(Render Tree)
  • 进行布局 Layout(回流/重排):根据生成的渲染树,得到节点的几何信息(位置,大小)
  • 进行绘制 Painting(重绘): 根据计算和获取的信息进行整个页面的绘制
  • Display: 展示在页面上

3.2. 重绘和回流(重排)

回流(重排)

  • 当 Render Tree 中部分或者全部元素的尺寸、结构、布局等发生改变时,浏览器就会重新渲染部分或全部文档的过
    程称为 回流。
    重绘
  • 由于节点(元素)的样式的改变并不影响它在文档流中的位置和文档布局时(比如:color、background-color、outline等), 称为重绘。
  • 重绘不一定引起回流,而回流一定会引起重绘。
    在这里插入图片描述
    在这里插入图片描述
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不能瞌睡呀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值