02-webAPI-事件基础

153 阅读4分钟

1 事件概述

1.什么是事件?

1.事件是在编程时系统内发生的动作或者发生的事情 比如用户在网页上单击一个按钮

2.什么是事件监听?

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

3.语法

元素.addEventListener('事件',要执行的函数)
btn1.addEventListener('click', function () {
       console.log('开始抽奖啦');
  });

4.事件监听三要素:

1.事件源: 那个dom元素被事件触发了,要获取dom元素

2.事件: 用什么方式触发,比如鼠标单击 click、鼠标经过 mouseover 等

3.事件调用的函数: 要做什么事

5.案列

//1.获取元素
let html= document.querySelector('html')
//2.事件监听 (注册事件)
      html.addEventListener('mousemove',function () {
          console.log('潮吧肖耀');
      })
<!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;
      }
      div {
        height: 300px;
        background-color: aqua;
      }
    </style>
  </head>
  <body>
    <button class="btn1">抽奖</button>
    <button class="btn2">退出抽奖</button>
    <div></div>
    <script>
      /* 
      触发事件dom元素
      事件类型
      事件触发了 做业务 函数
       */

      let btn1 = document.querySelector('.btn1');

      // 注册事件
      // btn1.addEventListener("事件类型","处理函数")

      // click 鼠标单击
      btn1.addEventListener('click', function () {
        console.log('开始抽奖啦');
      });

      let btn2 = document.querySelector('.btn2');
      btn2.addEventListener('click', function () {
        console.log('退出抽奖啦');
      });
      let div = document.querySelector('div');
      // mouseover  鼠标移入到 div 的区域内
      div.addEventListener('mouseover', function () {
        console.log('小哥快点进来');
      });
      let html= document.querySelector('html')
      html.addEventListener('mousemove',function () {
          console.log('潮吧肖耀');
      })
    </script>
  </body>
</html>

2.事件基础

1.JavaScript 使我们有能力创建动态页面,而事件是可以被 JavaScript 侦测到的行为

2.简单理解: 触发--- 响应机制。

3.网页中的每个元素都可以产生某些可以触发 JavaScript 的事件,例如,我们可以在用户点击某按钮时产生一个 事件,然后去执行某些操作

4.案列

//页面中有一个按钮,当鼠标点击按钮的时候,弹出“你好”警示框。
/*
1.获取事件源(按钮)
2.注册事件(绑定事件),使用 onclick
3.添加事件处理程序(采取函数赋值形式)
(编写事件处理程序,写一个函数弹出 alert 警示框)
*/
<buttton class="btn">点我</button>
var btn = document.getElementById('.btn');
btn.onclick = function() {
  alert('你好吗');  
};

2.常见的鼠标事件

2.常见的鼠标事件

鼠标事件触发条件
click鼠标点击左键触发
mouseover ,mouseenter鼠标经过触发
mouseout ,mouseleave鼠标离开触发
focusr获得鼠标焦点触发
blur失去鼠标焦点触发
mousemove鼠标移动触发
mouseup鼠标弹起触发
mousedown鼠标按下触发
contextmenu用户点击鼠标右键打开上下文菜单时触发
dblclick鼠标双击左键

3.焦点事件

焦点事件表单获得光标
focus获得焦点
blur失去焦点

4.键盘事件

键盘事件键盘触发
Keydown键盘按下触发
Keyup键盘抬起触发
keypress键盘按键被按下并松开

5.文本事件

文本事件表单输入触发
input用户输入事件

3.高级函数

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

【值】就是 JavaScript 中的数据,如数值、字符串、布尔、对象等。

1 函数表达式

1.函数表达式和普通函数并无本质上的区别:

数也是【数据】 把函数赋值给变量

//函数表达式与普通函数本质上是一样的
let counter = function (x,y){
    return x + y
}
//调用函数
let resule = counter(5,10)
console.log(result)
//普通函数的声明与调用无顺序限制,推荐做法先声明再调用
//函数表达式必须要先声明再调用

2.函数回调

如果将函数 A 做为参数传递给函数 B 时,我们称函数 A 为回调函数

简单理解:当一个函数当做参数来传递给另外一个函数的时候,这个函数就是回调函数

function fn () {
    console.log('我是回调函数')
}
//fn传递给   setInterval,fun就是函数回调
setInterval(fn,1000)
box.addEventListener('click' , function(){
    console.log('我也是回调函数')
})

把函数当做另外一个函数的参数传递,这个函数就叫回调函数

回调函数本质还是函数,只不过把它当成参数使用

使用匿名函数做为回调函数比较常见

4.环境对象

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

1.作用:

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

2.函数的调用方式不同,this 指代的对象也不同

3.【谁调用, this 就是谁】 是判断 this 指向的粗略规则

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

5.排他思想

<!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 {
        list-style: none;
        width: 600px;
        height: 100px;
        display: flex;

        margin: 100px auto;
        border: 1px solid #ccc;
      }
      li {
        display: flex;
        flex: 1;
        align-items: center;
        justify-content: center;
        font-size: 30px;
      }
    </style>
  </head>
  <body>
    <ul>
      <li>1</li>
      <li>2</li>
      <li>3</li>
    </ul>

    <script>
      // 先获取到每一个li标签
      // 再li标签绑定点击事件

      // 写处理其他所有的元素 让让他们的背景颜色都变成白色
      // 事件触发 设置 被点击的li标签 选中的样式

      // let liList = document.querySelectorAll('li');
      // for (let index = 0; index < liList.length; index++) {
      //   liList[index].addEventListener('click', function () {
      //     // 给被点击的li标签加上选中样式
      //     // liList[index].style.backgroundColor = 'red';
      //     // 先设置每一个li标签的背景颜色 成 白色
      //     for (let j = 0; j < liList.length; j++) {
      //       liList[j].style.backgroundColor = '#fff';
      //     }
      //     // 再单独设置 被点击的li标签  变成红色
      //     this.style.backgroundColor = 'red';
      //   });
      // }

      let liList = document.querySelectorAll('li'); // 获取所有的li标签 数组

      for (let index = 0; index < liList.length; index++) {
        // 对所有的li标签  开始绑定点击事件
        liList[index].addEventListener('click', function () {
          // 设置所有的li标签 背景颜色为白色
          setAllLiColor();
          // 设置被点击的li标签 为红色
          this.style.backgroundColor = 'red';
        });
      }

      // 设置所有li标签的背景颜色为白色
      function setAllLiColor() {
        for (let j = 0; j < liList.length; j++) {
          liList[j].style.backgroundColor = '#fff';
        }
      }
    </script>
  </body>
</html>

6.综合案列

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>
  </head>
  <body>
    <h1></h1>
    <button class="btn1">开始随机点名</button>
    <button class="btn2">结束点名</button>

    <script>
      /* 
      优化
      1 把数组的定义 提取到外面 
      2 如果定时器中业务比较繁琐 也可以提取出去到单独函数中 不是必须
      3 bug 点击多次 开始抽奖 ,后面无法停止定时器
        在我们行业中 有专业的术语 节流!! 
        让我们的顺序 一一个的执行 一次一次的执行 不要同时执行多个 

        在一个定时器没有执行结束的时候 不让开启另外一个定时器 

        一个班级的人 都想去上厕所 !! 
        你想要去上厕所的时候 
        1 先看一下里面有没有人
        2 有人了 我就不去  

        3 没有人 我进去了 会把门关上 
        4 解决完毕了 出去同时把门打开 
      
      4 如何解决 点击多次按钮 后面停止定时器的bug n种解法
        1 在开启定时器的时候 我直接禁用了button 不让它再次点击 
          在清除定时器  重新启用按钮即可

        2 在每一次开启定时器的之前,都停止一次定时器

      5 同学思考
        是否可以理解 老师说 你的案例写不够多的时候 不可能一写就写出来  简洁的代码 

        1 给时间你去练习  先自己写一写 感受一下  (写出来 写不出来 无所谓 )

        2 到老师开始讲解案例
          1 吸收老师写案例的 思路、代码编写顺序、习惯、 业务逻辑 
          2 当场就理解老师的案例 (不够清晰、不够熟练)
          3 晚自习或者休息天 时候  继续 巩固使用 熟悉它 
       */

      let btn1 = document.querySelector('.btn1');
      let btn2 = document.querySelector('.btn2');
      let h1 = document.querySelector('h1');
      let arr = ['张飞', '赵云', '刘备', '吕布', '刘婵'];
      let timeId;

      // 定时器要执行的业务逻辑
      function intervalDo() {
        let index = Math.round(Math.random() * (arr.length - 1));
        h1.innerText = arr[index];
        // return undefined
      }

      btn1.addEventListener('click', function () {
        // 先停止定时器 第一次清除 定时器的时候  timeId 是undefined
        // if (timeId) {
        if (timeId !== undefined) {
          // timeId = 是 undefined => bool 是false
          // 当timeId = undefined =false    不满足条件 不会执行 清除了
          clearInterval(timeId);
        }

        // 禁用按钮 不让再次点击
        // btn1.disabled = true;
        timeId = setInterval(intervalDo, 100);
        console.log('开启定时器', timeId);
      });

      btn2.addEventListener('click', function () {
        // 重新启用 开始按钮
        // btn1.disabled = false;
        clearInterval(timeId);
      });
    </script>
  </body>
</html>

2.全选打勾全选取消


<!DOCTYPE html>

<html>

<head lang="en">
  <meta charset="UTF-8">
  <title></title>
  <style>
    * {
      margin: 0;
      padding: 0;
    }

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

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

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

    .allCheck {
      width: 80px;
    }
  </style>
</head>

<body>
  <table>
    <tr>
      <th class="allCheck">
        <input type="checkbox" name="" id="checkAll"> <span class="all">全选</span>
      </th>
      <th>商品</th>
      <th>商家</th>
      <th>价格</th>
    </tr>
    <tr>
      <td>
        <input type="checkbox" name="check" class="ck">
      </td>
      <td>小米手机</td>
      <td>小米</td>
      <td>¥1999</td>
    </tr>
    <tr>
      <td>
        <input type="checkbox" name="check" class="ck">
      </td>
      <td>小米净水器</td>
      <td>小米</td>
      <td>¥4999</td>
    </tr>
    <tr>
      <td>
        <input type="checkbox" name="check" class="ck">
      </td>
      <td>小米电视</td>
      <td>小米</td>
      <td>¥5999</td>
    </tr>
  </table>
  <script>
    // 1. 获取元素  全选 和   ck 小复选框
    let all = document.querySelector('#checkAll')
    let cks = document.querySelectorAll('.ck')
    let span = document.querySelector('span')
    // 2. 事件监听   全选按钮  
    all.addEventListener('click', function () {
      // console.log(all.checked)  // true  false 
      // 我们需要做的就是把 all.checked 给下面三个小按钮
      // 因为三个按钮在伪数组里面,我们需要遍历的方式,挨着取出来,依次给值
      for (let i = 0; i < cks.length; i++) {
        cks[i].checked = all.checked
      }
      // 当我们的全选按钮处于选中状态,则可以改为取消
      if (all.checked) {
        // console.log('要改')
        span.innerHTML = '取消'
      } else {
        span.innerHTML = '全选'
      }
    })


    // 3. 小按钮的做法 同时给多个元素绑定相同事件
    for (let i = 0; i < cks.length; i++) {
      // 绑定事件
      cks[i].addEventListener('click', function () {
        // console.log(11)
        // 只要点击任何一个小按钮,都要遍历所有的小按钮  
        for (let j = 0; j < cks.length; j++) {
          // 都来看看是不是有人没有选中
          if (cks[j].checked === false) {
            // 如果有false 则退出循环 结束函数
            all.checked = false
            span.innerHTML = '全选'
            return
          }
        }
        // 当我们的循环结束,如果代码走到这里,说明没有false,都被选中了,则全选按钮要选中
        all.checked = true
        span.innerHTML = '取消'
      })
    }

  </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">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style>
    div {
      width: 80px;
    }

    input[type=text] {
      width: 50px;
      height: 44px;
      outline: none;
      border: 1px solid #ccc;
      text-align: center;
      border-right: 0;
    }

    input[type=button] {
      height: 24px;
      width: 22px;
      cursor: pointer;
    }

    input {
      float: left;
      border: 1px solid #ccc;

    }
  </style>
</head>

<body>
  <div>
    <input type="text" id="total" value="1" readonly>
    <input type="button" value="+" id="add">
    <input type="button" value="-" id="reduce" disabled>
    <script>
      // 1. 获取元素  三个
      let total = document.querySelector('#total')
      let add = document.querySelector('#add')
      let reduce = document.querySelector('#reduce')
      // 2. 点击加号 事件侦听  
      add.addEventListener('click', function () {
        total.value++
        reduce.disabled = false
      })
      // 3. 点击减号 事件侦听  
      reduce.addEventListener('click', function () {
        total.value--
        if (total.value <= 1) {
          reduce.disabled = true
        }
      })
      // 2 === '2'
    </script>
  </div>
</body>

</html>

4.小米搜索框


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

        ul {

            list-style: none;
        }

        .mi {
            position: relative;
            width: 223px;
            margin: 100px auto;
        }

        .mi input {
            width: 223px;
            height: 48px;
            padding: 0 10px;
            font-size: 14px;
            line-height: 48px;
            border: 1px solid #e0e0e0;
            outline: none;
        }

        .mi .search {
            border: 1px solid #ff6700;
        }

        .result-list {
            display: none;
            position: absolute;
            left: 0;
            top: 48px;
            width: 223px;
            border: 1px solid #ff6700;
            border-top: 0;
            background: #fff;
        }

        .result-list a {
            display: block;
            padding: 6px 15px;
            font-size: 12px;
            color: #424242;
            text-decoration: none;
        }

        .result-list a:hover {
            background-color: #eee;
        }
    </style>

</head>

<body>
    <div class="mi">
        <input type="search" placeholder="小米笔记本">
        <ul class="result-list">
            <li><a href="#">全部商品</a></li>
            <li><a href="#">小米11</a></li>
            <li><a href="#">小米10S</a></li>
            <li><a href="#">小米笔记本</a></li>
            <li><a href="#">小米手机</a></li>
            <li><a href="#">黑鲨4</a></li>
            <li><a href="#">空调</a></li>
        </ul>
    </div>
    <script>
        //1. 获取元素  
        let search =document.querySelector('input')   //input表单
        let list =document.querySelector('.result-list')  //下拉菜单
        //2.事件监听  获得光标事件  focus
        search.addEventListener('focus',function () {
            //显示下拉菜单
            search.classList.add('search')
            //文本框变色
            list.style.display = 'block'
        } )
        //3.事件监听  失去光标事件
        search.addEventListener('blur',function () {
            //隐藏下拉菜单
            search.classList.remove('search')
            //文本框去色
            list.style.display = 'none'
        } )
    </script>
</body>

</html>

5.微博输入案列 基础


<!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="10" maxlength="200"></textarea>
      <div>
        <span class="useCount">0</span>
        <span>/</span>
        <span>200</span>
        <button id="send">发布</button>
      </div>

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

      </ul>
    </div>
  </div>
  <script>
      //1.获取元素
      let area =document.querySelector('#area')   //文本域
      let useCount =document.querySelector('.useCount')     //   0
      //2.事件监听   用户输入事件    input
      area.addEventListener('input',function () {
        //不断得到文本域里面的字符长度  
        //area.value  可以得到用户输入的值
        //area.value.length       //得到用户输入的值的长度
        useCount.innerHTML=area.value.length  
      })
  </script>
</body>

</html>

6.tab栏案列

<!DOCTYPE html>
<html>

<head lang="en">
  <meta charset="UTF-8" />
  <title></title>
  <style type="text/css">
    * {
      margin: 0;
      padding: 0;
    }

    ul {
      list-style: none;
    }

    .wrapper {
      width: 1000px;
      height: 475px;
      margin: 0 auto;
      margin-top: 100px;
    }

    .tab {
      border: 1px solid #ddd;
      border-bottom: 0;
      height: 36px;
      width: 320px;
    }

    .tab li {
      position: relative;
      float: left;
      width: 80px;
      height: 34px;
      line-height: 34px;
      text-align: center;
      cursor: pointer;
      border-top: 4px solid #fff;
    }

    .tab span {
      position: absolute;
      right: 0;
      top: 10px;
      background: #ddd;
      width: 1px;
      height: 14px;
      overflow: hidden;
    }

    .products {
      width: 1002px;
      border: 1px solid #ddd;
      height: 476px;
    }

    .products .main {
      float: left;
      display: none;
    }

    .products .main.active {
      display: block;
    }

    .tab li.active {
      border-color: red;
      border-bottom: 0;
    }
  </style>
</head>

<body>
  <div class="wrapper">
    <ul class="tab">
      <li class="tab-item active">国际大牌<span></span></li>
      <li class="tab-item">国妆名牌<span></span></li>
      <li class="tab-item">清洁用品<span></span></li>
      <li class="tab-item">男士精品</li>
    </ul>
    <div class="products">
      <div class="main active">
        <a href="###"><img src="imgs/guojidapai.jpg" alt="" /></a>
      </div>
      <div class="main">
        <a href="###"><img src="imgs/guozhuangmingpin.jpg" alt="" /></a>
      </div>
      <div class="main">
        <a href="###"><img src="imgs/qingjieyongpin.jpg" alt="" /></a>
      </div>
      <div class="main">
        <a href="###"><img src="imgs/nanshijingpin.jpg" alt="" /></a>
      </div>
    </div>
  </div>
<script>

      let li =document.querySelectorAll('.tab-item')   //获取所有li标签
      let div = document.querySelectorAll('.products .main')    //获取prducts 里面的所有 main标签
      // console.log(li);
      // console.log(div);
      for (let index = 0; index < li.length; index++) {   //循环所有li标签
          li[index].addEventListener('click',function () { //点击事件
            document.querySelector('.active').classList.remove('active') //所有标签去掉红色上边框
            this.classList.add('active') //自己添加红色上边框
            //去掉products标签里面的 active标签
            document.querySelector('.products .active').classList.remove('active')
            //给products标签里面的 div添加  active标签
            div[index].classList.add('active')
          })  

      }
</script>


</body>

</html>