js:事件+高阶函数+环境变量+编程思想

105 阅读3分钟

事件

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

比如用户在网页上单击一个按钮

事件监听

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

语法:

//对象.addEventListener('事件类型',事件逻辑) 

事件监听三要素:

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

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

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


        //获取元素
        let btn = document.querySelector('button');
        //事件监听
        btn.addEventListener('click', function() {
                document.body.innerHTML = '你好';
            })

注意:

事件类型要加引号

函数是点击之后再去执行,每次点击都会执行一次

关闭二维码案例

<!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>
        .box1 {
            position: relative;
            height: 200px;
            width: 200px;
            background-color: aqua;
        }
        
        .box2 {
            position: absolute;
            top: 0;
            right: 0;
            height: 30px;
            width: 30px;
            background-color: red;
            text-align: center;
            line-height: 30px;
        }
    </style>
</head>

<body>
    <div class="box1">
        <div class="box2">x</div>
    </div>
    <script>
        let box1 = document.querySelector('.box1'),
            box2 = document.querySelector('.box2');
        box2.addEventListener('click', function() {


            box1.style.display = 'none'


        })
    </script>
</body>

</html>

随机点名案例

 <h1></h1>
    <button class="box1">点击按钮</button>
    <button class="box2">停止</button>
    <script>
        let arr = ['旋涡鸣人', '宇智波斑', '宇智波佐助', '宇智波鼬', '波风水门'];
        let h1 = document.querySelector('h1'),
            box1 = document.querySelector('.box1'),
            box2 = document.querySelector('.box2');

        box1.addEventListener('click', function() {
            minue = setInterval(function() {
                    let i = Math.round(Math.random() * (arr.length - 1))
                    h1.innerHTML = `${arr[i]}`
                },
                100)

        });
        box2.addEventListener('click', function() {
            clearInterval(minue);
        })
    </script>

优化随机点名案例

上面一个案例有节流问题。

节流的个人理解:就像一个水管有多个水龙头,我将这些水龙头都打开了,这时,我只能关闭最后一个水龙头,其他水龙头接着开着,导致水流不止。

    <h1></h1>
    <button class="box1">点击按钮</button>
    <button class="box2">停止</button>
    <script>
        let arr = ['旋涡鸣人', '宇智波斑', '宇智波佐助', '宇智波鼬', '波风水门'];
        let h1 = document.querySelector('h1'),
            box1 = document.querySelector('.box1'),
            box2 = document.querySelector('.box2');

        //输出的minue 是Undefined
        let minue;

        box1.addEventListener('click', function() {
            //undefined=false,minue为true时,就关闭一次定时器
            if (minue) {
                clearInterval(minue)
            }
            minue = setInterval(function() {
                    let i = Math.round(Math.random() * (arr.length - 1))
                    h1.innerHTML = `${arr[i]}`
                },
                100)

        });
        box2.addEventListener('click', function() {
            clearInterval(minue);
        })
    </script>

时间监听版本

DOM L0

​ 事件源.on事件 = function() { }

DOM L2

​ 事件源.addEventListener(事件, 事件处理函数)

发展史:

​ DOM L0 :是 DOM 的发展的第一个版本; L:level

​ DOM L1:DOM级别1 于1998年10月1日成为W3C推荐标准

​ DOM L2:使用addEventListener注册事件

​ DOM L3: DOM3级事件模块在DOM2级事件的基础上重新定义了这些事件,也添加了一些新事件类型。

时间类型

1649422592047

微博输入案例

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

<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>微博发布</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
        
        ul {
            list-style: none;
        }
        
        .w {
            width: 900px;
            margin: 0 auto;
        }
        
        .controls textarea {
            width: 878px;
            height: 100px;
            resize: none;
            border-radius: 10px;
            outline: none;
            padding-left: 20px;
            padding-top: 10px;
            font-size: 18px;
        }
        
        .controls {
            overflow: hidden;
        }
        
        .controls div {
            float: right;
        }
        
        .controls div span {
            color: #666;
        }
        
        .controls div .useCount {
            color: red;
        }
        
        .controls div button {
            width: 100px;
            outline: none;
            border: none;
            background: rgb(0, 132, 255);
            height: 30px;
            cursor: pointer;
            color: #fff;
            font: bold 14px '宋体';
            transition: all 0.5s;
        }
        
        .controls div button:hover {
            background: rgb(0, 225, 255);
        }
        
        .controls div button:disabled {
            background: rgba(0, 225, 255, 0.5);
        }
        
        .contentList {
            margin-top: 50px;
        }
        
        .contentList li {
            padding: 20px 0;
            border-bottom: 1px dashed #ccc;
            position: relative;
        }
        
        .contentList li .info {
            position: relative;
        }
        
        .contentList li .info span {
            position: absolute;
            top: 15px;
            left: 100px;
            font: bold 16px '宋体';
        }
        
        .contentList li .info p {
            position: absolute;
            top: 40px;
            left: 100px;
            color: #aaa;
            font-size: 12px;
        }
        
        .contentList img {
            width: 80px;
            border-radius: 50%;
        }
        
        .contentList li .content {
            padding-left: 100px;
            color: #666;
            word-break: break-all;
        }
        
        .contentList li .the_del {
            position: absolute;
            right: 0;
            top: 0;
            font-size: 28px;
            cursor: pointer;
        }
    </style>
</head>

<body>
    <div class="w">
        <!-- 操作的界面 -->
        <div class="controls">

            <!-- maxlength 可以用来限制表单输入的内容长度 -->
            <textarea placeholder="说点什么吧..." id="area" cols="30" rows="10" maxlength="200"></textarea>
            <div>
                <span class="useCount" id="useCount">0</span>
                <span>/</span>
                <span>200</span>
                <button id="send">发布</button>
            </div>
        </div>
        <!-- 微博内容列表 -->
        <div class="contentList">
            <ul id="list">

            </ul>
        </div>
    </div>
    <script>
        let useCount = document.querySelector('#useCount');
        let area = document.querySelector('#area');
        let send = document.querySelector('#send');
        let ul = document.querySelector('#list');
        send.addEventListener('click', function() {
            let li = document.createElement('li');
            li.innerText = area.value;
            ul.appendChild(li);
            area.value = '';
            useCount.innerHTML = 0
        });
        area.addEventListener('input', function() {
            useCount.innerHTML = area.value.length
        })
    </script>

</body>

</html>

全选文本框案例

<!DOCTYPE html>

<html>

<head lang="en">
    <meta charset="UTF-8" />
    <title>01-全选商品</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>
        let all = document.querySelector('#checkAll'),
            a = document.querySelectorAll('.ck');


        all.addEventListener('click', function() {
            for (let i = 0; i < a.length; i++) {
                a[i].checked = all.checked;
            }
        })
        for (let i = 0; i < a.length; i++) {
            a[i].addEventListener('click', function() {
                let checked = istrue();
                all.checked = checked;
            })
        }
        //函数封装功能(判断true or false)
        function istrue() {
            //1.存放选中商品的数量
            let num = 0;
            //2.遍历商品数组
            for (let i = 0; i < a.length; i++) {
                //3.判断商品选中状态
                if (a[i].checked) {
                    num++
                }
            }
            // 4.循环结束了,判断 选中商品的数量和商品总数量之间的关系
            if (num === a.length) {
                //商品全选
                return true;
            } else {
                //商品不全选
                return false
            }
        }
    </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>
        * {
            padding: 0;
            margin: 0;
            box-sizing: border-box;
        }
        
        .shop {
            margin: 100px auto;
            height: 60px;
            width: 100px;
            border: 1px solid black;
            display: flex;
            justify-content: flex-start;
        }
        
        input {
            width: 70%;
            height: 100%;
            border: none;
            text-align: center;
            line-height: 100%;
        }
        
        .right {
            flex: 1;
            display: flex;
            flex-direction: column;
            justify-content: flex-start;
            text-align: center;
        }
        
        .add {
            background-color: gray;
            height: 50%;
            color: #fff;
        }
        
        .reduce {
            height: 50%;
            color: red;
        }
    </style>
</head>

<body>
    <div class="shop">
        <input type="text" value="1">
        <div class="right">
            <button class="add">+</button>
            <button class="reduce">-</button>
        </div>
    </div>
    <script>
        let input = document.querySelector('input'),
            add = document.querySelector('.add'),
            reduce = document.querySelector('.reduce');

        add.addEventListener('click', function() {
            input.value++;
            reduce.disabled = false;
        })
        reduce.addEventListener('click', function() {
            input.value--;
            if (input.value == 1) {
                reduce.disabled = 'true';
            }
        })
    </script>
</body>

</html>

高阶函数

高阶函数可以被简单理解为函数的高级应用,JavaScript 中函数可以被当成【值】来对待,基于这个特性实现函数的高级应用。 【值】就是 JavaScript 中的数据,如数值、字符串、布尔、对象等。

函数表达式

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

1649429056658

普通函数的声明与调用无顺序限制,推荐做法先声明再调用

函数表达式必须要先声明再调用

回调函数

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

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

1649429139344

1649429153016

环境变量

环境对象指的是函数内部特殊的变量 this ,它代表着当前函数运行时所处的环境 作用:弄清楚this的指向,可以让我们代码更简洁

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

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

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

编程思想

排他思想

当前元素为A状态,其他元素为B状态

使用:

  1. 干掉所有人 使用for循环
  2. 复活他自己 通过this或者下标找到自己或者对应的元素

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 list = document.querySelectorAll('.tab-item');
        let div = document.querySelectorAll('.main')
        for (let i = 0; i < list.length; i++) {

            list[i].addEventListener('click', function() {
                for (let j = 0; j < list.length; j++) {
                    list[j].classList.remove('active');

                }

                this.classList.add('active');

                for (let j = 0; j < div.length; j++) {
                    div[j].style.display = 'none'

                }

                div[i].style.display = 'block'
            })

        }
    </script>
</body>

</html>