04.webAPI基础知识总结

278 阅读8分钟

1.web API基础认知

1-1.作用:

​ 就是使用 JS 去操作 html 和浏览器

1-2.分类:

​ DOM (文档对象模型)、BOM(浏览器对象模型

1648991276657

1-3.什么是DOM

  • DOM(Document Object Model——文档对象模型)是用来呈现以及与任意 HTML 或 XML文档交互的API

  • 白话文:DOM是浏览器提供的一套专门用来操作网页内容的功能

  • DOM作用:开发网页内容特效和实现用户交互

1-4.DOM树

  • 概念:
    • 将 HTML 文档以树状结构直观的表现出来,我们称之为文档树或 DOM 树
    • 描述网页内容关系的名词
    • 作用:文档树直观的体现了标签与标签之间的关系

1-5.DOM对象(重要)

  • DOM对象:浏览器根据html标签生成的 JS对象
    • 所有的标签属性都可以在这个对象上面找到
    • 修改这个对象的属性会自动映射到标签身上
  • DOM的核心思想
    • 把网页内容当做对象来处理
  • document 对象
    • 是 DOM 里提供的一个对象
    • 所以它提供的属性和方法都是用来访问和操作网页内容的
    • 网页所有内容都在document里面

2.获取DOM对象

2-1选择匹配的第一个元素

语法

1648991726415

参数

​ 包含一个或多个有效的CSS选择器 字符串

返回值:
  • CSS选择器匹配的第一个元素,一个 HTMLElement对象
  • 如果没有匹配到,则返回null

2-2选择匹配的多个元素

语法:

1649043532372

参数:
  • 包含一个多多个有效的css选择器字符串
返回值:
  • css选择器匹配的Nodelist 对象集合

1649043646048

注意:
  • 得到的是一个伪数组
  • 有长度有索引的数组
  • 但是没有pop() push()等数组方法
  • 想要得到里面的每一个对象。则需要遍历(for)的方式获得

2-3.其他获得DOM元素的方法(了解) 1649053482305

3.设置/修改DOM元素内容

3-1.document

  • document.write()
  • 只能将文本内容追加到前面的位置
  • 文本包含的标签会被解析

1649053749204

3-2.对象.innerText属性

  • 将文本内容添加/更新到任意 标签位置
  • 文本中包含的标签不会被解析

1649075988105

3-3.对象.innerHTML属性

  • 将文本内容添加/更新到任意标签位置
  • 文本中包含的标签也会被解析

1649076061024

4.设置/修改DOM元素属性

4-1设置/修改元素常用属性

  • 最常见的属性比如: href、title、src 等

1649076295590

4-2设置/修改元素样式属性

通过 style 属性操作CSS

1649076429531

操作类名(className) 操作CSS

1649076480883

通过 classList 操作类控制CSS
  • 为了解决className 容易覆盖以前的类名,我们可以通过classList方式追加和删除类名

1649076527761

4-3设置/修改表单元素属性

  • 表单很多情况,也需要修改属性,比如点击眼睛,可以看到密码,本质是把表单类型转换为文本框

  • 正常的有属性有取值的 跟其他的标签属性没有任何区别

1649076991962

5.定时器-间歇函数

5-1开启定时器

  • setInterval(函数,间隔时间)

1649077226215

5-2关闭定时器

1649077254706

6全选案例


<!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>
        table {
            width: 500px;
            height: 300px;
            margin: 100px auto;
            text-align: center;
            border-collapse: collapse;
        }
        thead {
            height: 50px;
            background-color: aquamarine;
        }
    </style>
</head>
<body>
    <table border="1">
        <thead>
            <tr>
                <th><input type="checkbox" class="checkAll">全选</th>
                <th>商品名称</th>
                <th>商家</th>
                <th>商品价格</th>
            </tr>
        </thead>
        <tbody>
        </tbody>
    </table>
    <script>
        let arr = [
            {name:'小米手机',business:'小米',price:'1999元'},
            {name:'小米净化器',business:'小米',price:'4999元'},
            {name:'小米电视',business:'小米',price:'5999元'},
        ]
        let html = ``
        let tbody = document.querySelector('tbody')
        for (let index = 0; index < arr.length; index++) {
            html +=`
                <tr>
                    <td><input type="checkbox" class="ck"></td>
                    <td>${arr[index].name}</td>
                    <td>${arr[index].business}</td>
                    <td>${arr[index].price}</td>
                </tr>
            `  
        }

        // console.log(html);
        tbody.innerHTML = html

        // 1 获取元素
        let checkAll = document.querySelector('.checkAll')
        let checkList = document.querySelectorAll('.ck')

        // 2 设置全选点击事件
        checkAll.addEventListener('click',function(){
            let state = checkAll.checked
            for (let index = 0; index < checkList.length; index++) {
                checkList[index].checked = state 
            }
        })

        // 3 设置单选点击事件
        for (let index = 0; index < checkList.length; index++) {
            checkList[index].addEventListener('click',function(){
                // 默认选中
                let state = true
                for (let index = 0; index < checkList.length; index++) {
                    // 如果有一个单选按钮未选中就设置全选按钮为未选中,且退出循环
                    if(checkList[index].checked==false){
                        state = false
                        break
                    }    
                }
                // 设置全选按钮默认为选中状态
                checkAll.checked = state
            })  
        }


    </script>
</body>
</html>

7.事件

事件是在编程时系统内发生的动作或者发生的事情

7-1事件监听

概念
  • 就是让程序检测是否有事件产生,一旦有事件触发,就立即调用一个函数做出响应,也称为 注册事件
语法:

1649075136363

事件监听三要素
  • 事件源

    • 那个dom元素被事件触发了,要获取dom元素
  • 事件

    • 用什么方式触发,比如鼠标单击click、鼠标经过mouseover等
  • 事件调用的函数

    • 要做什么事

7-2事件监听版本

  • DOM L0 :是 DOM 的发展的第一个版本; L:level
  • DOM L1:DOM级别1 于1998年10月1日成为W3C推荐标准,会覆盖事件
  • DOM L2:使用addEventListener注册事件,重复绑定事件,不会覆盖
  • DOM L3: DOM3级事件模块在DOM2级事件的基础上重新定义了这些事件,也添加了一些新事件类型

7-3事件类型

鼠标事件
  • click 鼠标点击
  • mouseenter 鼠标经过
  • mouseleave 鼠标离开
  • mouseover鼠标经过
  • mouseout 鼠标离开
焦点事件
  • focus 获得焦点
  • blur 失去焦点
键盘事件
  • keydown 键盘按下触发
  • keyup 键盘抬起触发
表单事件
  • input 用户输入事件

8.高阶函数

8-1概念

  • 高阶函数可以被简单理解为函数的高级应用,JavaScript 中函数可以被当成【值】来对待,基于这个特性实现函数的

8-2函数表达式

  • 函数也是数据
  • 把函数赋值给变量

8-3回调函数

  • 把函数当做另外一个函数的参数传递,这个函数就叫做回调函数
  • 回调函数本质还是函数,只不过把它当做成参数使用
  • 使用匿名函数作为回调函数比较常见

9.环境对象

9-1.概念:

  • 环境对象值的是函数内部特殊的变量this,它代表当前函数运行时所处的环境

9-2.作用:

  • 弄清楚this的指向,可以让我代码更简洁

  • 函数的调用方式不同,this只代的对象也不同

  • 谁调用,this就是谁,是判断this指向的粗略规则

  • 直接调用函数,其实相当于是window函数,所以this指代window

10.编程思想

10-1排他思想:

概念:
  • 当前元素为A状态,其他元素为B状态
使用:
  • 干掉所有人
    • 使用for循环
  • 复活他自己
    • 通过this或者下标找到自己或者对用的元素

11.节点操作

11-1DOM节点

概念:
  • DOM树里每一个内容都叫节点
分类:
  • 元素节点

11-2查找节点

父节点查找
  • parentNode属性
  • 返回最近一级的父节点 找不到返回null
子节点查找
  • childNodes
    • 获得所有 子节点 包括文本节点(空格 换行)、注释节点等
  • children (重点)
    • 仅获得所有元素的节点
    • 返回的还是一个伪数组
兄弟关系查找
  • 下一个兄弟节点

    • nextElementSibling
  • 上一个兄弟节点

    • previousElementSibling

11-3增加节点

创建节点
  • 即创造出一个新的网页元素,再添加到网页内,一般先创建节点,然后插入节点

1649238488115

追加节点
  • 要想在界面看到,还得插入到某个父元素中
  • 插入到父元素的最后一个子元素:

1649238575086

  • 插入到元素中的某个子元素的前面

1649238638097

克隆节点 1649245247245

11-4删除节点

1649245278148

删除自己

1649304219051

12.时间对象

12.1获得当前时间

1649311942844

12.2获得指定时间

1649311989286

12.3属性

1649312021729

    <script>
        let span = document.querySelector('span')
        setInterval(function(){
            let time = new Date()
            let year = time.getFullYear()
            let month = time.getMonth()
            let date = time.getDate()
            let day = time.getDay()
            let hour = time.getHours()
            let minutes = time.getMinutes()
            let seconds = time.getSeconds()
                span.innerText = `现在是北京时间:${year}${month+1}${date}日 星期${day} ${hour}${minutes}${seconds}秒`
            },1000)
    </script>

12.4时间戳

  • 是指1970年01月01日00时00分00秒起至现在的毫秒数,它是一种特殊的计量时间的方式

  • 三种方式获取时间戳

    1.使用getTime()方法

1649312306694

2.简写+new Date

1649312362301

13.微博发布案例

<!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>
    <link rel="stylesheet" href="css/weibo.css" />
  </head>

  <body>
    <div class="w">
      <div class="controls">
        <img src="images/tip.png" alt="" /><br />
        <textarea
          placeholder="说点什么吧..."
          id="area"
          cols="30"
          rows="100"
          maxlength="200"
        ></textarea>
        <div>
          <span class="useCount">0</span>
          <span>/</span>
          <span>200</span>
          <button id="send">发布</button>
        </div>
      </div>
      <div class="contentList">
        <ul>
          <!-- <li>
            <div class="info">
              <img class="userpic" src="./images/9.5/06.jpg" />
              <span class="username">张良</span>
              <p class="send-time">发布于 2022-4-7 15:12:23</p>
            </div>
            <div class="content">sdfdf</div>
            <span class="the_del">X</span>
          </li> -->
        </ul>
      </div>
    </div>
    <script>
      /* 
      1 给发布按钮绑定点击事件 
        1 生成一个li标签
          1 给li添加属性和子元素 
          2 获取文本域的内容 设置到对应的标签中 
        2 插入到ul中 

      2 给文本域绑定 input事件 
        获取文字的长度 设置对应的标签上 文字个数标签上

      3 给删除标签 绑定点击事件
        1 获取它的父节点 parentNode 
        2 让它父节点 删除自己 remove()

       */

      let dataArr = [
        { uname: '司马懿', imgSrc: './images/9.5/01.jpg' },
        { uname: '女娲', imgSrc: './images/9.5/02.jpg' },
        { uname: '百里守约', imgSrc: './images/9.5/03.jpg' },
        { uname: '亚瑟', imgSrc: './images/9.5/04.jpg' },
        { uname: '虞姬', imgSrc: './images/9.5/05.jpg' },
        { uname: '张良', imgSrc: './images/9.5/06.jpg' },
        { uname: '安其拉', imgSrc: './images/9.5/07.jpg' },
        { uname: '李白', imgSrc: './images/9.5/08.jpg' },
        { uname: '阿珂', imgSrc: './images/9.5/09.jpg' },
        { uname: '墨子', imgSrc: './images/9.5/10.jpg' },
        { uname: '鲁班', imgSrc: './images/9.5/11.jpg' },
        { uname: '嬴政', imgSrc: './images/9.5/12.jpg' },
        { uname: '孙膑', imgSrc: './images/9.5/13.jpg' },
        { uname: '周瑜', imgSrc: './images/9.5/14.jpg' },
        { uname: '老夫子', imgSrc: './images/9.5/15.jpg' },
        { uname: '狄仁杰', imgSrc: './images/9.5/16.jpg' },
        { uname: '扁鹊', imgSrc: './images/9.5/17.jpg' },
        { uname: '马可波罗', imgSrc: './images/9.5/18.jpg' },
        { uname: '露娜', imgSrc: './images/9.5/19.jpg' },
        { uname: '孙悟空', imgSrc: './images/9.5/20.jpg' },
        { uname: '黄忠', imgSrc: './images/9.5/21.jpg' },
        { uname: '百里玄策', imgSrc: './images/9.5/22.jpg' },
      ];
      // 发布按钮
      let send = document.querySelector('#send');
      let area = document.querySelector('#area');
      let ul = document.querySelector('ul');
      let useCount = document.querySelector('.useCount');

      // 点击
      send.addEventListener('click', function () {
        let user=getUser();
        let liHtml = `
        <li>
            <div class="info">
              <img class="userpic" src="${user.imgSrc}" />
              <span class="username">${user.uname}</span>
              <p class="send-time">发布于 ${getFormatTime()}</p>
            </div>
            <div class="content">${area.value}</div>
            <span class="the_del">X</span>
          </li
        `;
        // 每点击一次 在旧标签的基础上来 拼接多一个标签
        ul.innerHTML += liHtml;

        // 暂时没有办法解决的  实现 点击删除!!  事件委托技术 优雅解决 
      });

      // area input事件
      area.addEventListener('input', function () {
        useCount.innerText = area.value.length;
      });

      // 函数 随机获取用户对象
      function getUser() {
        let index = Math.round(Math.random() * (dataArr.length - 1));
        let user = dataArr[index];
        return user;
      }

      // 获取有一定格式的时间
      function getFormatTime() {
        let nowDate = new Date();
        let fullyear = nowDate.getFullYear();
        let month = nowDate.getMonth();
        let date = nowDate.getDate();
        let hours = nowDate.getHours();
        let minutes = nowDate.getMinutes();
        let seconds = nowDate.getSeconds();

        month = month < 10 ? '0' + month : month;
        date = date < 10 ? '0' + date : date;
        hours = hours < 10 ? '0' + hours : hours;
        minutes = minutes < 10 ? '0' + minutes : minutes;
        seconds = seconds < 10 ? '0' + seconds : seconds;

        return `${fullyear}-${month}-${date} ${hours}:${minutes}:${seconds}`;
      }
    </script>
  </body>
</html>

14.重绘和回流

  • 重绘不一定引起回流,而回流一定会引起重绘

14.1回流

  • 当 Render Tree 中部分或者全部元素的尺寸、结构、布局等发生改变时,浏览器就会重新渲染部分或全部文档的过程称为 回流

14.2重绘

  • 由于节点(元素)的样式的改变并不影响它在文档流中的位置和文档布局时(比如:color、background-color、outline等), 称为重绘

14.3会导致回流(重绘)的操作

  • 页面的首次刷新
  • 浏览器的窗口大小发生改变
  • 元素的大小或位置发生改变
  • 改变字体的大小
  • 内容的变化(如:input框的输入,图片的大小)
  • 激活css伪类 (如::hover)
  • 脚本操作DOM(添加或者删除可见的DOM元素)
  • 简单理解影响到布局了,就会有回流

1649819083437

15.事件对象

15-1.获取事件对象:

概念
  • 也是个对象,这个对象里有事件触发时的相关信息
获取
  • 在事件绑定的回调函数的第一个参数就是事件对象,一般命名为event、ev、e
1649727111913

15-2.事件对象常用属性

属性
  • type

    • 获取当前的事件类型
  • clientX/clientY

    • 获取光标相对于浏览器可见窗口左上角的位置
  • offsetX/offsetY

    • 获取光标相对当前DOM元素左上角的位置
  • key

    • 用户按下的键盘键的值

    • 现在不提倡使用keyCode

            area.addEventListener('keydown', function (event) {
              // 判断按键是不是回车键
              if (event.key === 'Enter') {
                // console.log("执行和按钮一样的功能");
      
                // 给btn按钮绑定过点击事件,点击事件也是可以主动触发
                btn.click(); // 你点击了一下按钮
      
                // 解决按下回车 文本换行的效果
                // 文本域的默认的行为
                // 处理标签的默认行为
                // return false
                event.preventDefault(); // 阻止浏览器标签的默认行为  阻止a标签默认跳转行为
              }
            });
      

16.事件流

16-1.事件流与两个阶段说明

概念
  • 事件流指的是事件完整执行过程中的流动路径
  • 说明:假设页面里有个div,当触发事件时,会经历两个阶段,分别是捕获阶段、冒泡阶段
  • 简单来说:捕获阶段是 从父到子 冒泡阶段是从子到父

16-2.事件捕获和事件冒泡

事件捕获
  • 父到子
  • 参数true

1649820297118

事件冒泡
  • 子到父
  • 参数false(默认值)

1649820332673

16-3.阻止事件流动

阻止冒泡
  • 此方法可以阻断事件流动传播,不光在冒泡阶段有效,捕获阶段也有效

1649820503908

  • 鼠标经过事件
    • mouseover 和 mouseout 会有冒泡效果
    • mouseenter 和 mouseleave 没有冒泡效果(推荐)
阻止默认行为

1649821062943

  • 比如链接点击不跳转,表单域的不提交

    1649820884349

区别
  • 传统on注册
    • 同一个对象,后面注册的事件会覆盖前面注册(同一个事件
    • 直接使用null覆盖偶就可以实现事件的解绑
    • 都是冒泡阶段执行的
  • 事件监听注册
    • 语法: addEventListener(事件类型, 事件处理函数, 是否使用捕获
    • 后面注册的事件不会覆盖前面注册的事件(同一个事件)
    • 可以通过第三个参数去确定是在冒泡或者捕获阶段执行
    • 必须使用removeEventListener(事件类型, 事件处理函数, 获取捕获或者冒泡阶段)
    • 匿名函数无法被解绑

17.事件委托

17.1优点

  • 给父级元素加事件(可以提高性能)

17.2原理

  • 事件委托其实是利用事件冒泡的特点, 给父元素添加事件,子元素可以触发

17.3实现

  • 事件对象.target 可以获得真正触发事件的元素
    <script>
      const ul = document.querySelector('ul');
      ul.addEventListener('click', function (event) {
        // event.target.style.backgroundColor="red";
        // console.log(event.target);

        // 只有点击了li标签才触发
        // console.log(event.target.nodeName);// 当前点击的元素的标签名 大写
        if (event.target.nodeName === 'LI') {
          console.log('改变颜色');
          event.target.style.backgroundColor = 'red';
        }
      });
    </script>

18.学生信息案例

    <script>
      // 1.1 定义数组 负责存放表格要显示的数据
      let arr = [ ];
      const tbody = document.querySelector('tbody');
      // 2  给 录入绑定点击事件
      const add = document.querySelector('.add');
      const uname = document.querySelector('.uname');
      const age = document.querySelector('.age');
      const gender = document.querySelector('.gender');
      const salary = document.querySelector('.salary');
      const city = document.querySelector('.city');

      // 1.2 根据数组渲染页面
      renderTableByArr();

      // 2  按钮绑定点击事件
      add.addEventListener('click', function () {
        // 2.1 创建一个新的对象 把表单数据都合并到对象中
        const data = {
          // 学号
          id: Date.now(),
          // 姓名
          uname: uname.value,
          // 年龄
          age: age.value,
          // 性别
          gender: gender.value,
          // 薪资
          salary: salary.value,
          // 就业城市
          city: city.value,
        };

        // 老师打了一个 断点 来验证 上面的代码 没有写错
        // 2.2 给数组插入新的元素
        arr.push(data);

        // 2.3 数组发生改变  重新调用渲染页面的函数
        renderTableByArr();

        // 2.4 表单数据清空
        uname.value = '';
        age.value = '';
        gender.value = '男';
        salary.value = '';
        city.value = '北京';
      });
      // 3 tbody绑定点击事件,同时判断被点击的是不是 del 删除标签
      tbody.addEventListener('click', function (event) {
        // 3.1 判断当前点击的是不是a标签
        if (event.target.nodeName === 'A') {
          // <a data-index="2" href="javascript:" class="del">删除</a>
          // 获取到a标签 上存放的 index
          // event.target =  a标签的dom元素
          // console.dir(event.target.dataset.index)
          const index = event.target.dataset.index;
          // 3.3 执行数组删除元素
          arr.splice(index,1);
          // 3.4 调用根据数组渲染页面的函数 
          renderTableByArr();
        }
      });
      // 根据数组渲染表格
      function renderTableByArr() {
        let html = ``;
        for (let index = 0; index < arr.length; index++) {
          html += `
         <tr>
          <td>${arr[index].id}</td>
          <td>${arr[index].uname}</td>
          <td>${arr[index].age}</td>
          <td>${arr[index].gender}</td>
          <td>${arr[index].salary}</td>
          <td>${arr[index].city}</td>
          <td>
            <a data-index="${index}" href="javascript:" class="del">删除</a>
          </td>
        </tr>
         `;
        }
        // 把生成的tr插入到 tbody中
        tbody.innerHTML = html;
      }
    </script>

19.滚动事件和加载事件

19.1滚动事件

应用
  • 很多网页需要检测用户把页面滚动到某个区域后做一些处理, 比如固定导航栏,比如返回顶部
语法
  • 给window或document添加scroll事件

1649822839223

固定导航栏
        let nav = document.querySelector('nav')
        let header = document.querySelector('header')
        window.addEventListener('scroll',function(){
            let scrollTop = document.documentElement.scrollTop
            if(scrollTop>=100) {
                nav.classList.add('fixed')
                header.style.marginBottom = 100 + 'px';
            }else{
                nav.classList.remove('fixed')
                header.style.marginBottom = 0;
            }
        })

19.2加载事件

事件名load
  • 监听页面所有资源加载完毕
  • 给 window 添加 load 事件

1649901673180

事件名DOMContentLoaded
  • 当初始的 HTML 文档被完全加载和解析完成之后,DOMContentLoaded 事件被触发,而无需等待样式表、图像等完全加载
  • 监听页面DOM加载完毕
  • 给 document 添加 DOMContentLoaded 事件

1649901720751

20.元素大小的位置

20.1scroll家族

获取宽高
  • 获取元素的内容总宽高(不包含滚动条)返回值不带单位
  • scrollWidth和scrollHeight
        /* 
        scrollWidth  不包含滚动条的大小
        scrollHeight  等于容器可以滚动的大小  滚动条的大小的大小为17px
        */
        let scrollDom = document.querySelector('div')
        // 输出它宽高
        console.log(scrollDom.scrollHeight);
        console.log(scrollDom.scrollWidth);
获取位置
  • 获取元素内容往左、往上滚出去看不到的距离
  • scrollLeft和scrollTop
  • 这两个属性是可以修改的
   // 获取当前容器滚动了的距离scrollDom.addEventListener('scroll',function(){
            console.log(this.scrollLeft);
            console.log(this.scrollTop);
})
总结
        /* 
        1 页面滚动 使用 window.addEventListenner("scroll")事件
        2 页面的滚动距离 document.documentElement.scrollTop

        1 元素滚动 dom.addEventListenner("scroll")
        2 获取元素滚动的距离
           dom.scrollTop
           dom.scrollLeft

        3 scrollWidth 整个可以滚动的区间的宽度
        4 scrollHieght 整个可以滚动的区域的高度

        小细节 pc端的滚动条的大小17px  移动端的滚动条不占大小

        */

20.2offset家族

获取宽高
  • 获取元素的自身宽高、包含元素自身设置的宽高、padding、border
  • offsetWidth和offsetHeight
        let offsetDom = document.querySelector('.offset')

        // // 获取宽度和高度 包含这滚动条的大小 
        console.log(offsetDom.offsetWidth);
        console.log(offsetDom.offsetHeight);
获取位置
  • 获取元素距离自己定位父级元素的左、上距离
  • offsetLeft和offsetTop注意是只读属性
        // 获取当前元素距离 定位了的父元素的大小(找不到定位了的父元素,相对于页面来计算)
        console.log(offsetDom.offsetTop);
        console.log(offsetDom.offsetLeft);
总结
        /* 
        总结 offset家族
        1 offsetWidth  获取元素的宽度 包含这滚动条
        2 offsetHeight 获取元素的高度 包含这滚动条
        3 offsetLeft 获取定位了的父元素的 水平距离 左 
        4 offsetTop 获取定位了的父元素的 垂直距离 上
       */

20.3client家族

获取宽高
  • 获取元素的可见部分宽高(不包含边框,滚动条等)
  • clientWidth和clientHeight
        let clientDom = document.querySelector('.client')

        // 宽度和高度
        console.log(clientDom.clientWidth); // 不包含 滚动条(类似 scrollWidth)
        console.log(clientDom.clientHeight); // 不包含 滚动条(类似 scrollHeight)
获取位置
  • 获取左边框和上边框宽度
  • clientLeft和clientTop 注意是只读属性
        // 获取边框的大小
        console.log(clientDom.clientLeft); // 左边框
        console.log(clientDom.clientRight); // 有没有?
        console.log(clientDom.clientTop); // 上边框 

20.4区别

        // 区别
        // scollWidth     获取容器的宽度(包含滚动的区域)
        // offsetWidth    获取可视区域的宽度(包含滚动条)
        // clientWidth    获取可视区域的宽度(不包含滚动条)

        // scrollLeft    获取左侧滚动的距离
        // offsetLeft    获取和已经定位了的父级元素的左距离
        // clientLeft    获取左边框的大小

20.5屏幕大小改变事件

    <script>
        // let title = document.querySelector('title')
      // 页面大小发生变化了就会触发的事件 resize window来绑定
      window.addEventListener('resize', function (event) {
        console.log('页面大小发生变化了');
        // 移动端屏幕适配 rem   淘宝js库,flexible.js  作用  设置html的字体大小 为当前页面的宽度的十分之一
        // 获取当前页面的宽度
        console.log(document.body.offsetWidth);
        // 设置页面html标签的字体大小为屏幕的十分之一
        document.documentElement.style.fontSize =
          document.body.offsetWidth / 10 + 'px';

        // 响应式布局的时候  发一个js文件  方便根据当前页面的宽度 告诉我们屏幕的种类和宽度
        const width = document.body.offsetWidth;

        if (width > 1200) {
          document.querySelector('title').innerText = `大屏幕 ${width}`;
        } else if (width > 992) {
          document.querySelector('title').innerText = `中等屏幕 ${width}`;
        } else if (width > 768) {
          document.querySelector('title').innerText = `小屏幕 ${width}`;
        } else {
          document.querySelector('title').innerText = `极小屏幕 ${width}`;
        }
      });

21.购物车综合案例

    <script>
        // 购物车-实现步骤
        // 获取元素
        let carBody = document.querySelector('#carBody')
        let totalCountEle = document.querySelector('#totalCount')
        let totalPriceEle = document.querySelector('#totalPrice')

        // 1 动态渲染
        function init(){
            let htmlStr = ''
            // 遍历数据
            data.forEach(function(value,index){
                // console.log(123);
                htmlStr += `
                        <tr>
                            <td>
                            <input class="s_ck"  type="checkbox" ${value.state ? 'checked' : ''}/>
                            </td>
                            <td>
                            <img src="${value.img}" />
                            <p>${value.name}</p>
                            </td>
                            <td class="price">${value.price}</td>
                            <td>
                            <div class="count-c clearfix">
                                <button class="reduce" data-index = "${index}" ${value.count==1? 'disabled' : ''}>-</button>
                                <input type="text" value="${value.count}" />
                                <button class="add" data-index="${index}">+</button>
                            </div>
                            </td>
                            <td class="total">${value.price*value.count}¥</td>
                            <td>
                            <a href="javascript:" class="del" >删除</a>
                            </td>
                        </tr>
                        `
            })
            carBody.innerHTML = htmlStr
        }
        init()

        // 2 计算出总数和总价格
        function computerTotal(){
            let totalCount = 0
            let totalPrice = 0
            data.forEach(function(value,index){
                if(value.state){
                    totalCount++
                    totalPrice+=value.price*value.count
                }
            })
            totalCountEle.innerHTML = totalCount
            totalPriceEle.innerHTML = totalPrice
        }
        computerTotal()

        // 3 数量增减
        carBody.addEventListener('click',function(e){
            if(e.target.className=='add'){
                // console.log(123);
                let index = e.target.dataset.index;
                data[index].count++

                // 重新渲染
                init()
                // 重新计算
                computerTotal()
            }else if(e.target.className=='reduce'){
                let index = e.target.dataset.index
                data[index].count--

                // 重新渲染
                init()
                // 重新计算
                computerTotal()
            }


        })
        // 4 全选
        // 5 列表中的选中
        // 6 删除所选商品
        // 7 清理购物车
        // 8 数据删除
    </script>

22.轮播图综合案例


<!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>
        * {
            margin: 0;
            padding: 0;
        }
        .big {
            width: 815px;
        }

    </style>
</head>
<body>
    <h1>美女画廊</h1>
    <div>
    </div>
    <img class="big" src="./placeholder.png" alt="">
    <h3>选择图片</h3>
    <script>
        let div = document.querySelector('div')
        let big = document.querySelector('.big')
        let h3 = document.querySelector('h3')
        let index = 0

        // 1 定义数组
        let arr = [
            {small:"./1-small.jpg",big:"./1.jpg",title:"美女A"},
            {small:"./2-small.jpg",big:"./2.jpg",title:"美女B"},
            {small:"./3-small.jpg",big:"./3.jpg",title:"美女C"},
            {small:"./4-small.jpg",big:"./4.jpg",title:"美女D"}
        ]

        // 2 写一个函数负责渲染小图片
        function render(){
            let imgHtml = ''
            for (let index = 0; index < arr.length; index++) {
                imgHtml+=  `<img src="./${index+1}-small.jpg" alt="">`
            }
            div.innerHTML = imgHtml
        }

        // 调用渲染小图片
        render()

        // 3 遍历小图片 绑定点击事件
        let imgSmall = document.querySelectorAll('div img')
        for (let index = 0; index < imgSmall.length; index++) {
            imgSmall[index].addEventListener('click',function(){
                // console.log(123);
                renderByindex(index)
            })
            
        }

        // 根据下标来显示对应的内容
        function renderByindex(arrIndex){
            big.src = arr[arrIndex].big
            h3.innerHTML = arr[arrIndex].title
        }
        

    </script>
</body>
</html>

23.window对象

23.1 BOM(浏览器对象模型)

  • BOM(Browser Object Model ) 是浏览器对象模型
  • window 是浏览器内置中的全局对象,我们所学习的所有 Web APIs 的知识内容都是基于 window 对象实现的
  • window 对象下包含了 navigator、location、document、history、screen 5个属性,即所谓的 BOM (浏览器对象模型)
  • document 是实现 DOM 的基础,它其实是依附于 window 的属性

1649943328303

23.2 定时器-延时函数

  • JavaScript 内置的一个用来让代码延迟执行的函数,叫 setTimeout

1649943422729

  • setTimeout 仅仅只执行一次,所以可以理解为就是把一段代码延迟执行, 平时省略window
  • 清除延时函数

1649943482978

定时器

1649943554248

23.3 JS执行机制

1650099108025

23.4 location对象

属性
  • href 属性获取完整的 URL 地址,对其赋值时用于地址的跳转

1649943696466

  • search 属性获取地址中携带的参数,符号 ?后面部分

1649943713798

  • hash 属性获取地址中的啥希值,符号 # 后面部分

1649943726636

  • reload 方法用来刷新当前页面,传入参数 true 时表示强制刷新

1649943749558

23.5 navigator对象

  • 主要用来获取浏览器的信息
属性
  • 通过 userAgent 检测浏览器的版本及平台

1649943847763

23.6 histroy对象

history 的数据类型是对象,该对象与浏览器地址栏的操作相对应,如前进、后退、历史记录等

属性

1649943901405

  <body>
    <a href="http://www.baidu.com">百度</a>
    <button class="forward">前进</button>
    <button class="back">后退</button>
    <script>
      const forward = document.querySelector('.forward');
      forward.addEventListener('click', function () {
        // history.forward();
        history.go(1); // 前进一个记录
      });
      const back = document.querySelector('.back');
      back.addEventListener('click', function () {
        // history.back();
        history.go(-1); // 后退一个记录
      });
    </script>
  </body>

23.7递归

概念
  • 一个函数调用自己
使用场景
  • 1 有一个函数,可以打印出 一个dom元素的所有祖先元素

    • 不可能提前知道 这个a标签有多少个父元素
    • 这个函数接收一个参数,= dom
    • 如果这个dom元素有父元素,就继续调用自己函数
  • 2 假设你现在得了肺炎 警察叔叔

    • 先找你 -> 找你的邻居(得了肺炎) -> 找你的邻居的邻居(得了肺炎)->找你的邻居的邻居(得了肺炎)... 直到找到一个邻居 没事 警察叔叔 不找结束了
    const button = document.querySelector('button');
          getParent(button);
          function getParent(dom) {
            console.log(dom);
            if (dom.parentNode) {
              // 如果有父元素
              getParent(dom.parentNode);
            } else {
              console.log('结束啦');
            }
          }
    
          // 定时器 不主动清除,定时器永远执行下去
          // 延时器 只会执行一次
    
          // 延时器实现定时器的功能
    
          // 在延时器 又开启一个延时器,
    
    
          // 递归 自己调用自己  函数自己调用自己 
          let index=0;
          function func() {
            console.log(++index);
            setTimeout(func,1000);
          };
          func();
    

23.8屏幕大小改变事件

      // 页面大小发生变化了就会触发的事件 resize window来绑定
      window.addEventListener('resize', function (event) {
        console.log('页面大小发生变化了');
        // 移动端屏幕适配 rem   淘宝js库,flexible.js  作用  设置html的字体大小 为当前页面的宽度的十分之一
        // 获取当前页面的宽度
        console.log(document.body.offsetWidth);
        // 设置页面html标签的字体大小为屏幕的十分之一
        document.documentElement.style.fontSize =
          document.body.offsetWidth / 10 + 'px';

        // 响应式布局的时候  发一个js文件  方便根据当前页面的宽度 告诉我们屏幕的种类和宽度
        const width = document.body.offsetWidth;

        if (width > 1200) {
          document.querySelector('title').innerText = `大屏幕 ${width}`;
        } else if (width > 992) {
          document.querySelector('title').innerText = `中等屏幕 ${width}`;
        } else if (width > 768) {
          document.querySelector('title').innerText = `小屏幕 ${width}`;
        } else {
          document.querySelector('title').innerText = `极小屏幕 ${width}`;
        }
      });

24.swiper插件

25.补充

25-1.console.log和console.dir区别

      /* 
      区别在于  
      有时候 我们使用console.log 打印dom元素的时候 输出一个标签格式 而不是一个对象格式
      console.dir 输出dom元素的元素 总是 对象格式
       */
      const btn=document.querySelector("button");
      // console.log(btn);
      console.dir(btn);

25-2.区分属性和方法

      // 属性的获取和使用  不需要加括号
      // 方法加括号
      // document.body.style.display="none"// 属性
      // document.body.classList.add()// 方法 

      // 利用编辑器 只要你不是色盲 你知道怎么区分
      // document.body.style.display

      // document.body.classList.a

25-3.页面换肤功能

    <!-- 在网页中 提供一个标签 让用户选择颜色 -->
    <!-- color标签有兼容性问题 少用 了解 -->

    <input type="color" />
    <script>
      const colorInput = document.querySelector('input');

      // 需要给这个标签 绑定 change事件 -  选好了值之后,就会触发的一个事件
      colorInput.addEventListener('change', function () {
        // 通过 value属性来获取 选中的颜色
        // console.log(this.value);

        // 设置到body标签中即可
        document.body.style.backgroundColor = this.value;
      });

26.本地存储

26-1特性

  • 数据存储在用户浏览器中
  • 设置、读取方便、甚至页面刷新不丢失数据
  • 容量较大,sessionStorage和localStorage约 5M 左右

26-2localStorage

1 概念
  • 生命周期永久生效,除非手动删除 否则关闭页面也会存在
  • 可以多窗口(页面)共享(同一浏览器可以共享)
  • 以键值对的形式存储使用
2 存储数据
  • localStorage.setItem(key, value)
3 获取数据
  • localStorage.getItem(key)
4 删除数据
  • localStorage.removeItem(key) 删除一个
  • localStorage.clear(); 删除所有
5 存储复杂数据类型存储
  • 本地只能存储字符串,无法存储复杂数据类型.需要将复杂数据类型转换成JSON字符串,在存储到本地
  • JSON.stringify(复杂数据类型)
    • 将复杂数据转换成JSON字符串 存储 本地存储中
  • JSON.parse(JSON字符串)
    • 将JSON字符串转换成对象 取出 时候使用

26-3sessionStorage

概念
  • 本地存储的技术 sessionStorage 会话(打开页面到关闭页面之间过程 一次会话 ajax node)存储
  • 它的用法和 localStorage 用法一样
  • 区别只有一个
  • sessionStorage 关闭页面后 数据就丢失
  • localStorage 除非是用户主动删除 否则一直存在 直到天荒地老
使用
      //  存数据
      // sessionStorage.setItem("ss",123);
      //  取数据
      // console.log(sessionStorage.getItem("ss"));
      // 删除一个
      // sessionStorage.removeItem("ss")
      // 清空
      // sessionStorage.clear();

27.元素属性

27-1固有属性

  • 标签天生自带的属性 比如class id title等, 可以直接使用点语法操作
      // 获取 dom元素的固有属性  通过点语法来获取
      const a = document.querySelector('a');
      // 获取固有属性
      // console.log(a.href);
      // console.log(a.id);

      // 直接修改
      // a.href="http://www.qq.com";
      // a.id="top";

27-2自定义属性

  • 由程序员自己添加的属性,在DOM对象中找不到, 无法使用点语法操作,必须使用专门的API
  • getAttribute('属性名') // 获取自定义属性
  • setAttribute('属性名', '属性值') // 设置自定义属性
  • removeAttribute('属性名') // 删除自定义属性
      // 自定义属性 不能直接通过点语法来获取和设置
      // 获取 getAttribute("属性名")
      // console.log(a.hello);
      // console.log(a.aa);
      // console.log( a.getAttribute("hello") );
      // console.log( a.getAttribute("aa") );

      // 设置 setAttribute(key,value)
      // a.setAttribute("hello","123");

      // 删除掉属性 removeAttribute(key)
      // a.removeAttribute("hello");

      //  自定义属性 -> h5建议的 自定义属性
      // 属性的时候 data-xxx 开头
      //  获取的时候  a.dataset.xxx
      //  设置  a.dataset.index = 3;

      // console.log(a.dataset.index);
      // a.dataset.index = 3;

27-3总结

      /* 
      小结 
      标签的属性 有两种分为
      1 固有属性  比如 id href src     点语法的方式获取和设置 方便
      2 自定义属性
        1 随机自己瞎命名  
          <a  abc="123" >  
            获取 (getAttribute) 设置 setAttribute(key,value)  删除   removeAttribute(key)
        2 h5建议 data- xxx
          <a  data-abc="123" >  
            获取(a.dataset.abc)  设置(a.dataset.abc=456);
      3 最强大是  (getAttribute)  setAttribute removeAttribute 
            上述的这个方式,可以获取到任意的属性(固有属性和h5建议的自定义属性)
            <a data-index="0" id="nav" href="http://www.baidu.com" hello="no" aa="bb" >跳转</a >
      */

28.事件绑定和取消绑定

    <script>
      // const btn = document.querySelector('button');

      // // 普通函数
      // function func() {
      //   console.log('2022-04-15 14:32:26');
      // }
      // function func2() {
      //   console.log("func2");
      // }

      // // 绑定事件
      // btn.addEventListener('click', func);

      // // addEventListener 可以绑定多个同名事件
      // btn.addEventListener('click', func2);

      // setTimeout(function () {
      //   // 取消这个事件绑定
      //   btn.removeEventListener('click', func);
      // }, 5000);


      /* 
      1 addEventListener 可以绑定多个同名事件
      2 removeEventListener 可以取消对应的事件类型和事件处理函数

      3 无法取消 addEventListener 事件 对应的匿名函数 
      
       */

       const btn=document.querySelector("button");
       
       btn.addEventListener("click",function () {
         console.log("你好");
       })
      //  想要取消 这个 输出你好的行为
      btn.removeEventListener("click",???);
    </script>

29.事件流动

  <body>
    <div class="a">爷爷
      <div class="b">爸爸
        <div class="c">儿子</div>
      </div>
    </div>
    <script>
      /* 
      事件流动  3个阶段  
      1 最重要的冒泡阶段
      2 知道  捕获阶段 
        addEventListener 第三个参数  true|false 来进行切换
      3 目标阶段 了解一下 

       */
      const a=document.querySelector(".a");
      const b=document.querySelector(".b");
      const c=document.querySelector(".c");
      a.addEventListener("click",function () {
        console.log("爷爷");
      })
      b.addEventListener("click",function () {
        // 这个c 是最底层的元素 
        console.log("爸爸");
      })
      c.addEventListener("click",function () {
        // 这个c 是最底层的元素 
        console.log("儿子 目标阶段");
      })
    </script>
  </body>

30.字符串方法

    <script>
      // 我们在实际开发过程中,有很多需求要针对字符串做处理
      // js 帮我们封装了很多大量和实用 字符串方法
      // 先介绍一些

      // 转大写 转小写。
      // let msg = 'HELLODFDFDFDFDFD';

      // 广告 msg 大写
      // msg="HELLO";// 搞定  楼下大妈也会!!!  low 低级 不堪入目
      // console.log(msg.toUpperCase());

      // 转小写
      // console.log(msg.toLowerCase()); //转成小写

      // 字符串和数组很相似
      // 能不能把字符串 转成数组?
      const str="abcdefg"; //=> ["a","b","c","d","e","f","g"]
      // // split("")   分割
      // console.log(str.split(""));
      // const str = 'a-b-c-d-e-f-g'; // ["a","b","c","d","e","f","g"]
      // console.log(str.split('-'));

      // console.dir(str);

      /* 
      1 转大写  toUpperCase()

      2 转小写 toLowerCase()

      3 转数组 str.split('') 按照什么来分割你的字符串变成数组
       */
    </script>

30-1数组方法

      // 数组 补充 常用
      //
      // const arr = ['a', 'b', 'c', 'd'];

      // console.log(arr.join('')); // join 数组转字符串
      // console.log(arr.join('-')); // a-b-c-d 数组转字符串

      // 连接  数组和数组之间连接
      // const arr1 = ['1', '2', '3'];
      // const arr2 = ['a', 'b', 'c'];
      // 将两个数组合并成一个数组
      // console.log(arr1.concat(arr2));

      //字符串也有一个 concat 也是表示合并
      const str1 = '123';
      const str2 = 'abc';
      // console.log(str1.concat(str2));// 很少用  有什么用? 当你的键盘 + 键坏  使用它 
      console.log(str1 + str2); // 更加简单好理解
    </script>

31.正则表达式

31.1概念

  • 正则表达式(Regular Expression)是用于匹配字符串中字符组合的模式。在 JavaScript中,正则表达式也是对象
  • 通常用来查找、替换那些符合正则表达式的文本,许多语言都支持正则表达式

31.2作用

  • 表单验证(匹配
  • 过滤敏感词(替换
  • 字符串中提取我们想要的部分(提取

31.3语法

test() 方法
  • 用来查看正则表达式与指定的字符串是否匹配

  • 定义正则表达式

1649949110416

  • 检索查找是否匹配

    1649949233385

exec() 方法
  • 在一个指定字符串中执行一个搜索匹配

  • 定义正则表达式

    1650011694789

    1650011717618

  • 如果匹配成功,exec() 方法返回一个数组,否则返回null

31.4元字符

普通字符
元字符(特殊字符)
边界符
  • 表示位置,开头和结尾,必须用什么开头,用什么结尾
  • 如果 ^ 和 $ 在一起,表示必须是精确匹配。

1650013079924

        const str = `俊朗的外表,美丽的弧线,明星的妻子,自豪的荣誉,青春的记忆,梦幻的传奇,无尽的伤病,世人的指摘,自我的救赎,上帝的眷顾,这就是大卫贝克汉姆`

        // 定义规则  ^ 以什么开头
        // const reg = /^俊朗/ //以俊朗开头的
        // console.log(reg.test(str));  //返回true

        // 定义规则  $ 以什么结尾
        const reg = /贝克汉姆$/ //以贝克汉姆结尾的
        console.log(reg.test(str));  //返回true
量词

1650102591084

字符类
  • . 表示除了(换行符之外)任意字符
  • \d 表示数字
  • \D 不是数字之外的任意1个字符
  • \w 字母、数字、下划线
  • \W 除去了 字母 、数字、下划线 之外字符
  • \s 匹配空格
  • \S 除了空格之外的字符
  • [a-z] 表示 a 到 z 26个英文字母都可以
  • [A-Z] 表示字母大写都可以
  • [0-9] 表示 0~9 的数字都可以
  • [0-9a-zA-Z] 表示数字0-9 字母a-z大小写

1650103060901

31.5修饰符

  • 修饰符约束正则执行的某些细节行为,如是否区分大小写、是否支持多行匹配等
语法

1650103111965

替换 replace 替换

1650103154398

综合案例