04-JS-webAPI-const-事件对象-事件流-事件委托-事件滚动

121 阅读6分钟

04-JS-webAPI-const-事件对象-事件流-事件委托-事件滚动

1 const和let区别

const 作用:

在程序设计的时候,如果发现有一些数据 永远不会被更改

区别:

1 const 和 let 一样 也能声明变量

2 const 声明的变量不能被修改 let 可以随意修改

3 判断是不是修改 看它有没有重新写 = 号 或者 自增 自减少

4 能使用 const 就不用 let

5 不知道什么时候使用 const 的时候 就使用 let

图片演示:

92221920e0c1490b299cd3f804d2ac2

1649680023084

代码:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no"
    />
    <title>01-const.html</title>
    <style>
      * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
      }
    </style>
  </head>
  <body>
    <script>
      /* 
      早些时候js 声明变量 只能使用 var 
      es6(新版本的js) 出现之后  只使用let 或者 const 

      let 声明的变量 可以被修改
      const 声明的变量 不可以被修改 const 常量 固定不变!! 

      作用:
      在程序设计的时候,如果发现有一些数据 永远不会被更改
      优先使用const (后期不小心发现被修改了,报错 - 去解决错误)

      后期老师写代码
      能用const就用const ,不能用const 使用let
      永远不会去使用var 
       */

      //  const num = 1;
      // num = 2;
      // console.log(num);

      // 复杂类型的数据 补充
      // const 声明的变量不能被修改

      // const num = 1;
      // num = 2;

      // const arr=[];
      // // arr.push("呵呵");// 新增一个元素 但是并没有修改过 数组的地址
      // arr=123;// 修改
      // console.log(arr);

      /* 
      const 声明的变量不能被修改
      1 普通类型的数据  直接写 =  ,表示修改数据 报错
      2 复杂类型的数据 直接写 =  , 表示修改 报错
      3 复杂类型的数据 写 = 相当于重新开辟新空间
      
      
       */

      // const obj = {};
      // obj.name = '悟空';
      // //  console.log(obj);
      // obj = 123; // 报错 = 出现=> 开启新的内存空间 报错

      // 小结  const 不能被修改的判断的方式
      // 看它有没有写 = 号即可
      //

      const index = 10;
      index++; // index = index + 1 //报错

      /* 
      总结:
      1 const和let一样 也能声明变量
      2 const 声明的变量不能被修改 let 可以随意修改
      3 判断是不是修改 看它有没有重新写 = 号或者自增自减少
      4 能使用const 就不用let
      5 你不知道什么时候使用const 
        1 学习老师的代码
        2 就使用let 
       */
    </script>
  </body>
</html>

2 事件对象

1 获取事件对象

目标:能说出什么是事件对象

事件对象是什么?

也是个对象,这个对象里有事件触发时发生的相关信息

列如: 鼠标点击事件中,事件对象就存了鼠标点在哪个位置等信息

如何获取?

在事件绑定的回调函数的第一个参数就是事件对象

一般命名为 event ev e

							函数 ( 事件对象 )
元素 . addEventListener('click',function(event){
    
})

2 事件对象常见属性

目标: 能够使用常见事件对象属性

1 部分常见属性

1 type

​ 获取当前的事件类型

  <body>
    <div>点击点击</div>
    <script>
      // 获取按钮
      const btn = document.querySelector('div');

      btn.addEventListener('mousemove', function (event) {
        console.log(event.type); // 输出当前的事件类型  少用
      }
2 clientX clientY (html的左上角)

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

  <body>
    <div>点击点击</div>
    <script>
      // 获取按钮
      const btn = document.querySelector('div');

      btn.addEventListener('mousemove', function (event) {
        console.log(event.type); // 输出当前的事件类型  少用
        console.log(event.clientX,event.clientY );
         // 返回 鼠标的位置-参照物 页面的左上角即可
3 offsetX offsetY (当前父元素的左上角)

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

  <body>
    <div>点击点击</div>
    <script>
      // 获取按钮
      const btn = document.querySelector('div');

      btn.addEventListener('mousemove', function (event) {
        console.log(event.type); // 输出当前的事件类型  少用
        console.log(event.clientX,event.clientY );
         // 返回 鼠标的位置-参照物 页面的左上角即可

        console.log(event.offsetX,event.offsetY);
        // 返回鼠标的坐标,参照物 是被点击的元素的左上角
      });
    </script>
  </body>
4 key

​ 用户按下的键盘的值

​ 现在不提倡使用keyCode

  <body>
    <script>
      // 给body标签 绑定 键盘按下事件 keydown
      //用户按下那个按键,都会在打印台 输出  
      document.body.addEventListener('keydown', function (event) {
        console.log(event.key);// 当下按下的按键 ! 
      });
    </script>
  </body>

代码:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no"
    />
    <title>03-事件对象-常见属性</title>
    <style>
      * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
      }
      div{
        width: 300px;
        height: 400px;
        background-color: aqua;
        margin-left: 300px;
      }
    </style>
  </head>
  <body>
    <div>点击点击</div>
    <script>
      // 获取按钮
      const btn = document.querySelector('div');

      btn.addEventListener('mousemove', function (event) {
        // console.log(event.type); // 输出当前的事件类型  少用
        console.log(event.clientX,event.clientY );
         // 返回 鼠标的位置-参照物 页面的左上角即可
         
        console.log(event.offsetX,event.offsetY);
        // 返回鼠标的坐标,参照物 是被点击的元素的左上角
      });
    </script>
  </body>
</html>

3 具体的鼠标类型在第二天的事件类型中有

4 事件流-捕获与冒泡-阻止冒泡-目标阶段

目标:能够说出事件流两个阶段说明

事件流指的是事件完整执行过程中的流动路径

1649817534116

说明:假设页面里有个div,当触发事件时,会经历两个阶段,分别是 捕获阶段 冒泡阶段

1 捕获-冒泡

简单来说: 事件流动分成两个阶段

​ 1 捕获阶段是从 父元素到子元素

​ 2 冒泡阶段是从 子元素到父元素

1649680023086

2 在绑定事件中增加属性可以选择 使用 捕获 还是冒泡

我们可以修改触发事件 让它选择使用 捕获阶段还是冒泡阶段 ( 默认值 )

addEventListener 可以选择使用冒泡还是捕获

addEventListener(事件类型,事件处理函数,捕获还是冒泡(默认值 false,可以省略)) false 为冒泡

addEventListener("click",function(){}, true ) true 为捕获

3 阻止冒泡-stopPropagation

鼠标绑定经过事件也有捕获,冒泡两种效果

1649822023568

给绑定事件的元素添加 event.stopPropaganda( ) ; 即可阻止其的冒泡阶段,直接取当前元素的冒泡

      const c = document.querySelector('.c');
      c.addEventListener(
        'click',
        function (event) {
          console.log('c');
          p.innerText = +p.innerText + 100;
          p.style.backgroundColor = 'green';
          // 阻止事件冒泡
          event.stopPropagation();
        }
      );

4 目标阶段

目标阶段 是存在最里面的那个标签 并且被点击到 ,那个就是目标阶段

1650009869499

代码示例:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no"
    />
    <title>16-事件流动.html</title>
    <style>
      * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
      }
      div{
        width: 300px;
        height: 300px;
        padding: 20px;
        overflow: hidden;
      }
      .a{
        background-color: red;
      }
      .b{
        background-color: salmon;
      }
      .c{
        background-color: seagreen;
      }
    </style>
  </head>
  <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>
</html>

5 代码示例:

1 事件流动-捕获和冒泡

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no"
    />
    <title>01-事件流动捕获和冒泡.html</title>
    <style>
      * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
      }
      div {
        width: 200px;
        height: 200px;
        padding: 20px;
        overflow: hidden;
      }
      .a {
        background-color: red;
      }
      .b {
        background-color: blue;
      }
      .c {
        background-color: green;
      }
    </style>
  </head>
  <body>
    <div class="a"><div class="b"><div class="c"></div>
      </div>
    </div>
    <script>
      const a = document.querySelector('.a');
      a.addEventListener(
        'click',
        function () {
          console.log('a');
        },
        true
      ); // 捕获

      const b = document.querySelector('.b');
      b.addEventListener(
        'click',
        function () {
          console.log('b');
        },
        true
      ); // 捕获

      const c = document.querySelector('.c');
      c.addEventListener(
        'click',
        function () {
          console.log('c');
        },
        false
      );//冒泡

      /* 
      事件流动 
      1 给多个父子结构的标签绑定事件, 先点击了子元素, 产生事件流动
      2 事件流动 分成了两个阶段
        1 捕获阶段   父节点 流动到 子节点
        2 冒泡阶段   子节点 流动到 父节点   默认
        3 例子:
          人 跳水 
          1 水上跳 水里面 不断下沉 
          2 最后又从水里浮上去
        4 事件流动方向 默认是 使用了冒泡 - 点击儿子标签 触发  儿子-> 父亲->爷爷

      3 我们可以修改触发事件 让它选择使用 捕获阶段还是冒泡阶段(默认)
        addEventListener 可以选择使用冒泡还是捕获
        addEventListener(事件类型,事件处理函数,捕获还是冒泡(默认值 false,可以省略))  false 为冒泡
        addEventListener("click",function(){}, true )  true 为捕获
 
      4 总结
        1 捕获和 冒泡 特点 了解 
        2 默认情况  冒泡 如果想要修改 可以 addEventListener 第三个参数 传入 true即可
        3 以后的代码开发过程中,还是继续使用默认的 冒泡阶段 

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

2 阻止冒泡

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no"
    />
    <title>03-阻止冒泡</title>
    <style>
      * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
      }
      div {
        width: 200px;
        height: 200px;
        padding: 20px;
        overflow: hidden;
      }
      .a {
        background-color: red;
      }
      .b {
        background-color: blue;
      }
      .c {
        background-color: green;
      }
      p {
        width: 200px;
        height: 200px;
        background-color: yellow;
      }
    </style>
  </head>
  <body>
    <p>1</p>
    <div class="a"><div class="b"><div class="c"></div>
      </div>
    </div>
    <script>
      const p = document.querySelector('p');

      const a = document.querySelector('.a');
      a.addEventListener(
        'click',
        function () {
          p.style.backgroundColor = 'red';
          p.innerText = +p.innerText + 1;
          console.log('a');
        }
      ); 
      const b = document.querySelector('.b');
      b.addEventListener(
        'click',
        function (event) {
          console.log('b');
          p.innerText = +p.innerText + 10;
          p.style.backgroundColor = 'blue';
          // 阻止事件冒泡
          event.stopPropagation();
        }
      );
      const c = document.querySelector('.c');
      c.addEventListener(
        'click',
        function (event) {
          console.log('c');
          p.innerText = +p.innerText + 100;
          p.style.backgroundColor = 'green';
          // 阻止事件冒泡
          event.stopPropagation();
        }
      );


      /* 
      引出新的知识 阻止冒泡! 优雅的方式来解决刚才的问题! 
      在事件对象中 event 找到一个方法 停止冒泡  event.stopPropagation();
      
       */
    </script>
  </body>
</html>

小结:

1 捕获 和 冒泡 的区别( 捕获:父到子 冒泡: 子到父 )

2 默认情况 冒泡 如果想要修改 可以 addEventListener 第三个参数传入 true 即可

3 以后使用还是多用 冒泡阶段

5 阻止标签的默认行为-preventDefault

1 a 标签点击不跳转

2 form-button 点击刷新

3 鼠标右键弹出菜单

4 表单域的不提交

5 解决方法 : 给要阻止的元素添加 event . preventDefault ( ); 即可

代码示例:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no"
    />
    <title>04-阻止标签的默认行为.html</title>
    <style>
      * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
      }
    </style>
  </head>
  <body>
    <a href="http://www.baidu.com">百度</a>

    <form >
      <button>点击我 就会自动刷新</button>
      <!-- <input type="button" value="点击我"> -->
    </form>
    <button>刷新</button>
    <script>
      /* 
      1 a标签的点击跳转
      2 form表单中button点击刷新行为
        1 阻止默认行为 - form表单 有一个 submit 事件 理解提交表单的触发-点击按钮的时候触发
        2 给button按钮绑定点击事件 也去阻止试试
        3 给button按钮 添加一个 type="button" 属性 
        4 换成 input标签 type="button"
        5 把button 移出form表单的区域 

      使用新技术 阻止标签默认行为 
       */
      const a=document.querySelector("a");
      const form=document.querySelector("form");
      const button=document.querySelector("button");
      a.addEventListener("click",function (event) {
        console.log("a标签的点击触发啦");
        // 阻止a标签的默认行为,让他不要跳转
        event.preventDefault();
      })

      form.addEventListener("submit",function (event) {
      //   // 不要让页面再刷新
        event.preventDefault();
      })

      // button.addEventListener("click",function (event) {
           // 不要让页面再刷新
      //   event.preventDefault(); 
      // })
    </script>
  </body>
</html>

6 事件委托

目标:能够说出事件委托的好处

事件委托是利用事件流的特征解决一些开发需求的知识技巧

总结:

​ 1 优点: 给父级元素加事件 ( 可以提高性能 )

​ 2 原理: 事件委托骑士是利用事件冒泡的特点,给父元素添加事件,子元素可以触发

​ 3 实现: 事件对象 . target 可以获得真正触发事件的元素

代码示例:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no"
    />
    <title>06-事件委托感受.html</title>
    <style>
      * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
      }
      ul{
        width: 500px;
        background-color: aqua;
        padding: 50px;
      }
      li{
        background-color: yellow;
        height: 50px;
      }
      a{
        background-color: sandybrown;
      }
    </style>
  </head>
  <body>
    <ul>
      <li><a href="#">1</a></li>
      <li>2</li>
      <li>3</li>
      <li>4</li>
      <li>5</li>
    </ul>
    <script>
        // 以前的做法
      // 点击那个一li标签 颜色设置为红色
      // 以前获取到每一个li标签 数组  遍历他们 按个绑定点击事件
      // const liList=document.querySelectorAll("li");
      // for (let index = 0; index < liList.length; index++) {
      //    liList[index].addEventListener("click",function () {
      //      this.style.backgroundColor="red"
      //    })
      // }


      // 事件委托
      //  本来想要给 li 标签绑定事件实现业务
      //  把事件绑定写在  父元素上  把 li 标签应该要做的事情  委托给父元素来做  
      const ul=document.querySelector("ul");
      ul.addEventListener("click",function (event) {
        //  event.target 有可能是ul标签,有可能是li标签,还有可能是 a标签 
        // 一会再来解决这个问题。
        event.target.style.backgroundColor="red";// 不够完美的
        // event.target 你当前点击的是哪个标签(点击最深最底层的那个标签即可)
        // console.log(event.target);// 获取到被点击的li标签 
      })
    </script>
  </body>
</html>

代码示例-小结:

事件委托 原理 如冒泡阶段一样

本来想要给 li 标签绑定事件实现业务

把事件绑定写在 父元素上 把 li 标签应该要做的事情 委托给父元素来做

1649774060374

7-事件对象-获取被点击标签名称-event.target.nodeName

给元素添加点击事件对象后,添加 event.target.nodeName 则能获取点击标签的名称

案例示范:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no"
    />
    <title>07-event.target.nodeName</title>
    <style>
      * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
      }
      ul {
        width: 500px;
        background-color: aqua;
        padding: 50px;
      }
      li {
        background-color: yellow;
        height: 50px;
      }
      a {
        background-color: sandybrown;
      }
    </style>
  </head>
  <body>
    <ul>
      <li><a href="#">1</a></li>
      <li>2</li>
      <li>3</li>
      <li>4</li>
      <li>5</li>
    </ul>
    <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>
  </body>
</html>

8 滚动事件-scroll

1 整个页面滚动 window

给window来绑定scroll 事件

获取页面滚动距离 document.documentElement.scrollTop

2 某个元素滚动 就给元素绑定scroll 事件

3 也可以主动设置滚动距离 滚动距离为200

document.documentElement.scrollTop=200;

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no"
    />
    <title>12-固定导航-案例.html</title>
    <style>
      * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
      }
      header {
        height: 250px;
        background-color: yellow;
      }
      nav {
        background-color: orange;
        height: 150px;
        /* 粘性定位 兼容性问题  慎用!  */
        position: sticky;
        left: 0;
        top: 0;
        width: 100%;
      }

      div {
        /* height: 150vh; */
        background-color: aqua;
      }
    </style>
  </head>
  <body>
    <button>设置页面滚动距离 200</button>
    <header></header>
    <nav></nav>
    <div>
      <h1>1</h1>
      <h1>2</h1>
      <h1>3</h1>
      <h1>4</h1>
      <h1>5</h1>
      <h1>6</h1>
      <h1>7</h1>
      <h1>8</h1>
      <h1>9</h1>
      <h1>10</h1>
      <h1>11</h1>
      <h1>12</h1>
      <h1>13</h1>
      <h1>14</h1>
      <h1>15</h1>
      <h1>16</h1>
      <h1>17</h1>
      <h1>18</h1>
      <h1>19</h1>
      <h1>20</h1>
      <h1>21</h1>
      <h1>22</h1>
      <h1>23</h1>
      <h1>24</h1>
      <h1>25</h1>
      <h1>26</h1>
    </div>

    <script>
      const button = document.querySelector('button');
      button.addEventListener('click', function () {
        // 设置页面的滚动距离
        document.documentElement.scrollTop = 200;
      });
    </script>
  </body>
</html>

固定导航-案例示范:

<!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;
            box-sizing: border-box;
        }
        header{
            height: 250px;
            background-color: yellow;
        }
        nav{
            height: 150px;
            background-color: red;
        }
        div{
            background-color: blue;
        }
        .fixed{
            position: fixed;
            left: 0;
            top: 0;
            width: 100%;
        }
    </style>
</head>
<body>
    <header></header>
    <nav></nav>
    <div>
        <h1>1</h1>
        <h1>2</h1>
        <h1>3</h1>
        <h1>4</h1>
        <h1>5</h1>
        <h1>6</h1>
        <h1>7</h1>
        <h1>8</h1>
        <h1>9</h1>
        <h1>10</h1>
        <h1>11</h1>
        <h1>12</h1>
        <h1>13</h1>
        <h1>14</h1>
        <h1>15</h1>
        <h1>16</h1>
        <h1>17</h1>
        <h1>18</h1>
        <h1>19</h1>
        <h1>20</h1>
        <h1>21</h1>
        <h1>22</h1>
        <h1>23</h1>
        <h1>24</h1>
        <h1>25</h1>
        <h1>26</h1>
        <h1>27</h1>
        <h1>28</h1>
        <h1>29</h1>
        <h1>30</h1>
        <h1>31</h1>
        <h1>32</h1>
        <h1>33</h1>
        <h1>34</h1>
        <h1>35</h1>
        <h1>36</h1>
        <h1>37</h1>
        <h1>38</h1>
        <h1>39</h1>
        <h1>40</h1>
        <h1>41</h1>
        <h1>42</h1>
        <h1>43</h1>
        <h1>44</h1>
        <h1>45</h1>
        <h1>46</h1>
        <h1>47</h1>
        <h1>48</h1>
        <h1>49</h1>
        <h1>50</h1>
        <h1>51</h1>
        <h1>52</h1>
        <h1>53</h1>
        <h1>54</h1>
        <h1>55</h1>
        <h1>56</h1>
        <h1>57</h1>
        <h1>58</h1>
        <h1>59</h1>
        <h1>60</h1>
        <h1>61</h1>
        <h1>62</h1>
        <h1>63</h1>
        <h1>64</h1>
        <h1>65</h1>
        <h1>66</h1>
        <h1>67</h1>
        <h1>68</h1>
        <h1>69</h1>
        <h1>70</h1>
        <h1>71</h1>
        <h1>72</h1>
        <h1>73</h1>
        <h1>74</h1>
        <h1>75</h1>
        <h1>76</h1>
        <h1>77</h1>
        <h1>78</h1>
        <h1>79</h1>
        <h1>80</h1>
        <h1>81</h1>
        <h1>82</h1>
        <h1>83</h1>
        <h1>84</h1>
        <h1>85</h1>
        <h1>86</h1>
        <h1>87</h1>
        <h1>88</h1>
        <h1>89</h1>
        <h1>90</h1>
        <h1>91</h1>
        <h1>92</h1>
        <h1>93</h1>
        <h1>94</h1>
        <h1>95</h1>
        <h1>96</h1>
        <h1>97</h1>
        <h1>98</h1>
        <h1>99</h1>
        <h1>100</h1>
    </div>

    <script>
     /* 
      需求:  当页面滚动到一定的高度  nav变成了固定定位 
      1 一定高度 ???   其实就是header标签的高  250px

      步骤:
      1 需要在页面滚动距离 大于或者等于 250 的高时候 
        1 设置nav标签做一个 固定定位
      2 否则就取消固定定位  

      3 小bug 因为 nav标签做固定定位,不再拥有高度,自然把下面的标签给挡住!!! 
        解决它 
        给nav上面的标签 header标签 添加下外边距,大小 等于 nav的高
       */
        const nav=document.querySelector('nav')
        const header=document.querySelector('header')
        window.addEventListener('scroll',function(){
            // 获取页面滚动高度
            const sum=document.documentElement.scrollTop
            // 判断页面滚动高度
            if(sum>=250){
                nav.classList.add('fixed')
                header.style.marginBottom=150+'px'
            }else{
                nav.classList.remove('fixed')
                header.style.marginBottom=0
            }
        })
    </script>
</body>
</html>

9 H5自定义属性 data-xxx

要想使用标签自定属性,必须要在标签上增加 data-index(自定义名称)='1'(可以自己取值,也可以搭配循环使用 index )

才能在 JS 中 用 dataset.index 来获取

标签的自定义属性:

1 标签上的

2 js 中的dom.dataset.index 来获取

1649816497688

10 案例示范:

1-图片小鸟随鼠标移动

<!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>
        body{
            /* position: relative; */
            height: 100vh;
        }
        img{
            width: 100px;
            position: absolute;
            transform: translate(-50%,-50%);
            cursor: cell;
        }
    </style>
</head>
<body>
    <h3>用户鼠标不要移动那么快</h3>
    <img src="./images/1.png" alt="">
    <script>
       /* 
      1 给body标签 绑定 鼠标移动事件  
        body也是一个普通的块级元素 高度由内容撑开 同时 div使用了定位-脱标 body标签没有高度 
      2 事件触发了 获取 事件对象的坐标 clientX 
      3 把坐标设置给div的left top
       */
        let img=document.querySelector('img')
        document.body.addEventListener('mousemove',function(event){
            const left=event.clientX
            const top=event.clientY
            
            img.style.left= left + 'px'
            img.style.top= top + 'px'
        })
    </script>
</body>
</html>

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>
    <textarea name="" id="" cols="30" rows="10"></textarea>
    <button>发布</button>
    <ul></ul>
    <script>
     /* 
      步骤
      1 给发布按钮 绑定点击事件
        1 获取文本域的内容 
        2 拼接到一个新创建的li标签中
        3 把新创建的li标签插入到ul中

      2 给文本域 绑定键盘按下事件

        按下键盘之后  先判断当下按下的是不是回车  也去执行点击按钮的工作 即可 
       */
        let tex=document.querySelector('textarea')
        let btn=document.querySelector('button')
        let ul=document.querySelector('ul')

        btn.addEventListener('click',function(){
            if(tex.value.trim()===''){
            // 如果是空字符串,就直接返回,不再执行
                return
            }
            // 创建li
            let li=document.createElement('li')
            // li的文本内容 =  文本域的文本内容
            li.innerText=tex.value
            // ul 插入 li
            ul.appendChild(li)
            // 内容清 0
            tex.value=''
        })
        tex.addEventListener('keydown',function(event){
            // 判断按键是不是回车键
            if(event.key==='Enter'){
           // console.log("执行和按钮一样的功能");

           // 给btn按钮绑定过点击事件,点击事件也是可以主动触发
                btn.click() //你点击了一下按钮
                // event.preventDefault(); // 阻止浏览器标签的默认行为  阻止a标签默认跳转行为
            }
        })
    </script>
</body>
</html>

3 阻止默认行为-添加右键新菜单

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no"
    />
    <title>05-阻止默认行为.html</title>
    <style>
      * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
      }
      body {
        height: 100vh;
      }
      .menu {
        list-style: none;
        padding: 10px;
        border-radius: 5px;
        border: 1px solid #ccc;
        width: 150px;
        position: fixed;

        display: none;
      }
      li {
        height: 40px;
        display: flex;
        align-items: center;
        padding-left: 10px;
        border-bottom: 1px solid #ccc;
      }
      li:hover {
        background-color: skyblue;
        color: #fff;
        cursor: pointer;
      }
      li:last-child {
        border-bottom: none;
      }
    </style>
  </head>
  <body>
    <ul class="menu">
      <li>添加图标</li>
      <li>切换壁纸</li>
      <li>下载壁纸</li>
      <li>设置</li>
    </ul>
    <script>
      const menu = document.querySelector('.menu');
      // 不可能把一个技术的使用场景全部 讲解完毕
      // let 使用场景
      // 数组的使用场景
      // 定时器的使用场景
      // 函数的使用场景 
      // Math对象的使用场景
      // 钱的使用场景

      // 鼠标右键不要弹出 默认的菜单

      // 绑定鼠标右键事件 在 阻止默认行为
      // contextmenu 鼠标右键
      document.body.addEventListener('contextmenu', function (event) {
        event.preventDefault();
        // 坐标
        const left = event.clientX;
        const top = event.clientY;
        // 在body里右键点击时,标签显示
        menu.style.display = 'block';
        menu.style.left = left + 'px';
        menu.style.top = top + 'px';
      });
       // 在body里左键点击时,标签隐藏
      document.body.addEventListener('click', function () {
        menu.style.display = 'none';
      });
    </script>
  </body>
</html>

4 火箭点击回到顶部-优化动画效果

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no"
    />
    <title>16-小火箭导航-动画效果</title>
    <style>
      * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
      }
      body {
        height: 200vh;
        background-image: linear-gradient(black, red, blue, green);
      }
      a {
        width: 150px;
        height: 195px;
        position: fixed;
        bottom: 100px;
        right: 50px;
        background-image: url(http://md.zbztb.cn/uploads/201881139412/gotop.png);
        /* display: none; */
      }
      a:hover {
        background-image: url(http://md.zbztb.cn/uploads/201881139412/gotop.gif);
      }

      /* html{
        transition: 1s;
      } */
    </style>
  </head>
  <body>
    <!-- <a href="#"></a> -->
    <a href="javascript:;"></a>
    <script>
      /* 
      定时器来实现 
       */

      const a = document.querySelector('a');

      window.addEventListener('scroll', function () {
        //  获取页面滚动的距离
        const scrollTop = document.documentElement.scrollTop;
        if (scrollTop > 700) {
          // 显示火箭
          a.style.display = 'block';
        } else {
          // 隐藏
          a.style.display = 'none';
        }
      });

      a.addEventListener('click', function () {
        // document.documentElement.scrollTop = 0;
        // console.log(document.documentElement); // 就是根标签 html

        // 慢慢的来设置 scrollTop 减少为0 即可
        let timeId = setInterval(function () {
        // 滚动距离慢慢减少
          document.documentElement.scrollTop -= 20;
          console.log('定时器执行', document.documentElement.scrollTop);

          if (document.documentElement.scrollTop === 0) {
            // 清除定时器
            clearInterval(timeId);
          }
        }, 10);
      });
    </script>
  </body>
</html>

5 数据驱动视图-点击按钮-录入学生信息综合案例

重点:

要想使用标签自定属性,必须要在标签上增加 data-自定义名称='1'(可以自己取值,也可以搭配循环使用 index )

才能在 JS 中 用 dataset.index 来获取

标签的自定义属性:

1 标签上的

2 js 中的dom.dataset.index 来获取

思路分析:

1649680023087

代码:

<!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>08-综合案例-模版</title>
    <style>
      * {
        margin: 0;
        padding: 0;
      }

      a {
        text-decoration: none;
        color: #721c24;
      }
      h1 {
        text-align: center;
        color: #333;
        margin: 20px 0;
      }
      table {
        margin: 0 auto;
        width: 800px;
        border-collapse: collapse;
        color: #004085;
      }
      th {
        padding: 10px;
        background: #cfe5ff;

        font-size: 20px;
        font-weight: 400;
      }
      td,
      th {
        border: 1px solid #b8daff;
      }
      td {
        padding: 10px;
        color: #666;
        text-align: center;
        font-size: 16px;
      }
      tbody tr {
        background: #fff;
      }
      tbody tr:hover {
        background: #e1ecf8;
      }
      .info {
        width: 900px;
        margin: 50px auto;
        text-align: center;
      }
      .info input {
        width: 80px;
        height: 25px;
        outline: none;
        border-radius: 5px;
        border: 1px solid #b8daff;
        padding-left: 5px;
      }
      .info button {
        width: 60px;
        height: 25px;
        background-color: #004085;
        outline: none;
        border: 0;
        color: #fff;
        cursor: pointer;
        border-radius: 5px;
      }
      .info .age {
        width: 50px;
      }
    </style>
  </head>

  <body>
    <h1>新增学员</h1>
    <div class="info">
      姓名:<input type="text" class="uname" /> 年龄:<input
        type="text"
        class="age"
      />
      性别:
      <select name="gender" id="" class="gender">
        <option value="男"></option>
        <option value="女"></option>
      </select>
      薪资:<input type="text" class="salary" /> 就业城市:<select
        name="city"
        id=""
        class="city"
      >
        <option value="北京">北京</option>
        <option value="上海">上海</option>
        <option value="广州">广州</option>
        <option value="深圳">深圳</option>
        <option value="曹县">曹县</option>
      </select>
      <button class="add">录入</button>
    </div>

    <h1>就业榜</h1>
    <table>
      <thead>
        <tr>
          <th>学号</th>
          <th>姓名</th>
          <th>年龄</th>
          <th>性别</th>
          <th>薪资</th>
          <th>就业城市</th>
          <th>操作</th>
        </tr>
      </thead>
      <tbody>
        <!-- <tr>
          <td>1</td>
          <td>这是名称</td>
          <td>这是年龄</td>
          <td>这是性别</td>
          <td>这是工资</td>
          <td>这是所在城市</td>
          <td>
            <a href="javascript:" class="del">删除</a>
          </td>
        </tr> -->
      </tbody>
    </table>
    <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++) {
        // 要想使用自定义标签属性,,必须要给标签添加  data-index="${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>
  </body>
</html>