API-const-事件对象-事件流-事件委托-处理捕获和冒泡,和各类阻止加使用案例

112 阅读2分钟

const

1649664535170.png

<!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>

获取事件对象

1649664795884.png

<!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>

事件对象常见属性

<!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>

事件流

1649724112139.png

1649724967342.png

事件流动 分成了两个阶段 1 捕获阶段 父节点 流动到 子节点 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>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 水上 水里面 不断下沉 
        4 事件流动方向 默认是 使用了冒泡 - 点击儿子标签 触发 儿子->父亲->爷爷

      3 我们可以修改触发事件 让它选择使用 捕获阶段还是冒泡阶段(默认)
        addEventListener 可以选择使用冒泡还是捕获
        addEventListener(事件类型,事件处理函数,捕获还是冒泡(默认值 false,可以省略))
        addEventListener("click",function(){}, true )

      4 总结
        1 捕获和 冒泡 特点 了解 
        2 默认情况  冒泡 如果想要修改 可以 addEventListener 第三个参数 传入 true即可
        3 以后的代码开发过程中,还是继续使用默认的 冒泡阶段 


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

处理捕获和冒泡

<!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>02-处理捕获和冒泡</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');
        },
        true
      ); // 捕获
      const b = document.querySelector('.b');
      b.addEventListener(
        'click',
        function () {
          console.log('b');
          p.innerText = +p.innerText + 10;
          p.style.backgroundColor = 'blue';
        },
        true
      ); // 捕获
      const c = document.querySelector('.c');
      c.addEventListener(
        'click',
        function () {
          console.log('c');
          p.innerText = +p.innerText + 100;
          p.style.backgroundColor = 'green';
        },
        true
      );


      /* 
      引出新的知识 阻止冒泡! 下一节课 优雅的方式来解决刚才的问题! 
      
       */
    </script>
  </body>
</html>

阻止冒泡事件

<!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>

阻止标签的默认行为

<!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 type="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>

阻止右键默认选项并添加新选项

<!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;

        menu.style.display = 'block';
        menu.style.left = left + 'px';
        menu.style.top = top + 'px';
      });
      document.body.addEventListener('click', function () {
        menu.style.display = 'none';
      });
    </script>
  </body>
</html>

事件委托

1649732499295.png

1649733183375.png

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"
        //    })
        // }


        // 事件委托
        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>

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>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"
        //    })
        // }


        // 事件委托
        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标签 
            //解决点错标签的的方法,加一个判断就行
            if (event.target.nodeName === "LI") {
                event.target.style.backgroundColor = "red";
            }
        })
    </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>
    <style>
        ol {
            width: 500px;

        }
    </style>

</head>

<body>
    <div class="w">
        <div class="controls">
            <!-- <img src="images/tip.png" alt=""><br> -->
            <textarea placeholder="说点什么吧..." id="area" cols="30" rows="10" maxlength="1000"></textarea>
            <div>
                <span class="useCount">0</span>
                <span>/</span>
                <span>1000</span>
                <button id="send">发布</button>
            </div>

        </div>
        <div class="contentList">
            <ol>

            </ol>
        </div>
    </div>
    <script>
        let area = document.querySelector("#area")
        let useCount = document.querySelector(".useCount")
        let fa = document.querySelector('#send')
        let ul = document.querySelector("ol")
        area.addEventListener("input", function () {
            //字符串长度的值赋予显示字数
            useCount.innerText = area.value.length;
            //限制字数,有点小bug,复制粘贴的话,本身被复制的字数不算在限制里面
            // if (area.value > 200) {
            //     area.value = area.value.slice(0, 200)
            // }
        })
        //作业要求:1.点击发布的时候文本域显示字数  2.点发布的时候输出的文字生成一个存放的标签,同时清空文本域
        //思路:文本域早上做过了,直接c+v,点击发布的时候生成存放的标签,先写按钮点击事件,在里面写标签生成和插入,然后百度怎么清空文本域,,最后把早上的计算文本域字数的代码再复制丢进去就可以了,用ol还可以有序排列
        //发布按钮点击事件
        fa.addEventListener("click", function () {
            //创建一个新的li标签
            let li = document.createElement("li")
            //插入li标签
            ul.appendChild(li)
            //把文本域里面的内容(value:文本域属性)赋予li
            li.innerText = area.value
            //函数清空文本域里面的文字
            area.value = area.value.slice(0, 0)
            //把文本域的字符串长度的值赋予左边span标签的字数显示
            useCount.innerText = area.value.length;
        })
        //文本域的键盘事件
        area.addEventListener('keyup', function (e) {
            //判断用户是否按下回车键
            if (e.key === 'Enter') {
                //判断成功执行发布按钮事件
                fa.click()
            }

        })

    </script>
</body>

</html>

跟随鼠标移动案例

就是1 给body标签 绑定 鼠标移动事件
body也是一个普通的块级元素 高度由内容撑开 同时 div使用了定位-脱标 body标签没有高度 2 事件触发了 获取 事件对象的坐标 clientX 3 把坐标设置给div的left top

<!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;
      }
      /* div {
        width: 100px;
        height: 100px;
        background-color: aqua;
        position: fixed;
      } */
      img {
        position: fixed;
        /* width: 50px; */
        /* 移动自身宽度和高度的一半 */
        transform: translate(-50%, -50%);
      }
      body {
        height: 100vh;
        /* 隐藏鼠标 */
        cursor: none;
      }
    </style>
  </head>
  <body>
    <h1>用户鼠标不要移动那么快</h1>
    <!-- <div></div> -->
    <img src="./images/xn.png" alt="" />
    <script>
      /* 
      1 给body标签 绑定 鼠标移动事件  
        body也是一个普通的块级元素 高度由内容撑开 同时 div使用了定位-脱标 body标签没有高度 
      2 事件触发了 获取 事件对象的坐标 clientX 
      3 把坐标设置给div的left top
       */

      // const div = document.querySelector('div');
      const 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>

微博发布案例优化

就是判断用户是否输入的是空字符

<!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;
      }
    </style>
  </head>
  <body>
    <a href="http://www.baidu.com"></a>
    <textarea id="area"></textarea>
    <button>发布</button>
    <ul></ul>
    <script>
      /* 
      步骤
      1 给发布按钮 绑定点击事件
        1 获取文本域的内容 
        2 拼接到一个新创建的li标签中
        3 把新创建的li标签插入到ul中

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

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

      btn.addEventListener('click', function (event) {
        // 判断一下当前的文本域的内容 是不是空字符串
        if (area.value.trim() === '') {
          console.log('返回不再往下执行');
          return;
        }

        // area.value
        const li = document.createElement('li');
        li.innerText = area.value;
        ul.appendChild(li);
      });

      area.addEventListener('keydown', function (event) {
        // 判断按键是不是回车键
        if (event.key === 'Enter') {
          // console.log("执行和按钮一样的功能");

          // 给btn按钮绑定过点击事件,点击事件也是可以主动触发
          btn.click(); // 你点击了一下按钮

          // 解决按下回车 文本换行的效果
          // 文本域的默认的行为
          // 处理标签的默认行为
          // return false
          event.preventDefault(); // 阻止浏览器标签的默认行为  阻止a标签默认跳转行为
        }
      });

      document.querySelector('a').addEventListener('click', function (e) {
        e.preventDefault(); // 阻止a标签的默认 跳转行为
      });
    </script>
  </body>
</html>