JavaScript基础(四)- 事件监听、正则表达、模块化

目录

1.事件监听

 2.常见事件

 3.案例

表格隔行换色

表单校验

4.正则表达式

5. 模块化

6.总结


1.事件监听

JS事件监听的语法:

事件源.addEventListener('事件类型',要执行的函数);

在上述的语法中包含三个要素:

  • 事件源:哪个dom元素触发了事件,要获取dom元素(document.querySelector("...");)
  • 事件类型:用什么方式触发,比如:鼠标单击click,鼠标经过mouseover
  • 要执行的函数:要做什么事
<!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>JS-事件监听</title>
</head>

<body>
    <input type="button" id="btn1" value="点我一下试试1">
    <input type="button" id="btn2" value="点我一下试试2">

    <script>
        // 1.事件监听【推荐】--可以绑定多个事件
        document.querySelector("#btn1").addEventListener('click',() => {
            alter("试试就试试1~~");
        })

        document.querySelector("#btn1").addEventListener('click', function () {
            alert("试试就试试11111111~~");
        })

        // 2.事件监听(早期版本)--调用事件属性---只能绑定一次,后面的会覆盖前面
        document.querySelector("#btn2").onclick = () => {
            alert("试试就试试2");
        }

        document.querySelector("#btn2").onclick = () => {
            alert("试试就试试2222222");
        }

    </script>
</body>

</html>

上述的两种事件监听方法中,我们推荐第一种方法(使用addEventListener),原因是第二种方法只能绑定一次,后面的会被覆盖。

 2.常见事件

<script>
        //click: 鼠标点击事件
        document.querySelector('#b2').addEventListener('click', () => {
            console.log("我被点击了...");
        })

        //mouseenter: 鼠标移入
        document.querySelector('#last').addEventListener('mouseenter', () => {
            console.log("鼠标移入了...");
        })

        //mouseleave: 鼠标移出
        document.querySelector('#last').addEventListener('mouseleave', () => {
            console.log("鼠标移出了...");
        })

        //keydown: 某个键盘的键被按下
        document.querySelector('#username').addEventListener('keydown', () => {
            console.log("键盘被按下了...");
        })

        //keyup: 某个键盘的键被抬起
        document.querySelector('#username').addEventListener('keyup', () => {
            console.log("键盘被抬起了...");
        })

        //blur: 失去焦点事件
        document.querySelector('#age').addEventListener('blur', () => {
            console.log("失去焦点...");
        })

        //focus: 元素获得焦点
        document.querySelector('#age').addEventListener('focus', () => {
            console.log("获得焦点...");
        })

        //input: 用户输入时触发
        document.querySelector('#age').addEventListener('input', () => {
            console.log("用户输入时触发...");
        })

        //submit: 提交表单事件
        document.querySelector('form').addEventListener('submit', () => {
            alert("表单被提交了...");
        })
    </script>

 3.案例

表格隔行换色

 需求:实现表格隔行换色效果,奇数行设置背景色为: #FBFBD4,偶数行设置背景色为: #D9D9FA

效果:

分析:

  • 要改变表格的颜色,我们需要用dom来获取表格元素tr再进行操作
  • 要设置悬停时颜色改变效果,需要用到鼠标移入事件mouseenter和鼠标移出事件mouseleave。
<!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>JS-案例-隔行换色</title>
    <style>
        table {
            /* 设置表格的宽度 */
            width: 60%;
            /* 将表格边框合并,消除单元格之间的间距 */
            border-collapse: collapse;
            /* 将表格边框间的距离设置为0,确保没有任何间距 */
            border-spacing: 0;
            /* 文本居中对齐 */
            text-align: center;
            /* 版心居中展示 */
            margin: auto;
            /* 距离顶部的外边距 */
            margin-top: 20px;
            /* 行高 */
            line-height: 30px;
            /* 字体 */
            font-family: 'Courier New', 华文中宋, monospace;
        }

        table,
        tr,
        th,
        td {
            /* 设置表格的边框 */
            border: 1px solid black;
        }

        h1 {
            /* 文本居中对齐 */
            text-align: center;
        }

        .footer_btn {
            /* 文本居中对齐 */
            text-align: center;
            margin-top: 10px;
        }
    </style>
</head>

<body>
    <h1 id="title">用户信息表</h1>

    <table>
        <tr>
            <th>编号</th>
            <th>姓名</th>
            <th>年龄</th>
            <th>性别</th>
            <th>爱好</th>
        </tr>
        <tr class="data">
            <td>1</td>
            <td>Tom</td>
            <td>18</td>
            <td>男</td>
            <td>Java , JS , HTML , Vue</td>
        </tr>
        <tr class="data">
            <td>2</td>
            <td>Cat</td>
            <td>12</td>
            <td>女</td>
            <td>Java , JS , HTML , Vue</td>
        </tr>
        <tr class="data">
            <td>3</td>
            <td>Lee</td>
            <td>21</td>
            <td>男</td>
            <td>Java , Vue</td>
        </tr>
        <tr class="data">
            <td>4</td>
            <td>Jerry</td>
            <td>19</td>
            <td>女</td>
            <td>JS , HTML , Vue</td>
        </tr>
        <tr class="data">
            <td>5</td>
            <td>Jack</td>
            <td>25</td>
            <td>男</td>
            <td>Java</td>
        </tr>
        <tr class="data">
            <td>6</td>
            <td>Jones</td>
            <td>22</td>
            <td>女</td>
            <td>HTML , Vue</td>
        </tr>
    </table>

    <script>
        // 需求:实现表格隔行换色效果
        // 分析:事件--鼠标移入、移出事件,DOM操作tr元素,添加样式  style="background-color: antiquewhite;"
        //1.用dom获取表格元素tr(表头除外)
        let trs = document.querySelectorAll(".data");
        //获取到的所有的类名为data的<tr>元素的集合
        2.要对表格行数进行奇偶计算,我们用普通的for循环判断奇偶
        for(let i = 0; i < trs.length; i++)}
            const tr = trs[i];//将获取到的当前行元素存储在常量tr中,以便后续为该行添加鼠标事件监听
         //2.操作元素属性--奇数行设置#FBFBD4 ,偶数行设置#D9D9FA
         //鼠标移入事件
            tr.addEventListener('mouseenter',() => {
                if(i % 2 == 0)}
                    tr.style = "background-color: #FBFBD4;"
                }else{
                    tr.style = "background-color: #D9D9FA;"
                }
             })

         //3.鼠标移出事件
         tr.addEventListener('mouseleave',() => {
                tr.style = "background-color: #FFF;"
            })
        }

    </script>
</body>

</html>

表单校验

需求:完成用户注册的表单校验操作,要求做到以下两点。

  1. 在表单项中输入完成,鼠标离开焦点时,进行表单项内容的校验,如果内容格式不正确,显示提示信息。

  2. 在表单提交时,校验整个表单内容,如果内容格式有一项不正确,弹出提示信息,阻止表单数据提交。

效果:

分析:

  • 要对表单进行校验,我们需要用dom来获取表单元素再进行操作
  • JS的事件监听:离焦事件blur,表单提交事件submit
<!DOCTYPE html>
<html>

<head>
    <title>表单</title>
    <style>
        label {
            display: inline-block;
            width: 80px;
            text-align: right;
            margin-right: 10px;
        }

        input {
            width: 250px;
            padding: 10px;
            border: 1px solid #ccc;
            border-radius: 5px;
            margin-bottom: 10px;
        }

        .btn {
            width: 150px;
        }

        .tip {
            color: #ff0000;
            font-size: 12px;
        }
    </style>
</head>

<body>
    <div>
        <h1>用户注册</h1>
        <form>
            用户名:
            <input type="text" id="username" name="username" placeholder="用户名不能为空且长度在4-16个字符">
            <span class="tip" id="name_msg"></span> <br>

            手机号:
            <input type="text" id="phone" name="phone" placeholder="手机号不能为空且长度为11位">
            <span class="tip" id="phone_msg"></span>
            <br>

            <input type="submit" value="提交" class="btn">
            <input type="reset" value="重置" class="btn">
        </form>
    </div>


    <script>
        // 需求:表单校验--用户名:长度在4-16位;手机号:长度11位
        // 分析:JS事件--鼠标离焦事件blur, 表单提交事件submit,, DOM操作
        // 校验用户名
        // 1.获取dom元素
        let input = document.querySelector("#username");

        //匿名函数命名
        let checkUsername = () => {
            let flag = true;    //用来标识用户名是否合法
            let usernameValue = input.value;//要放到里面,当离焦的时候记录最新的用户名

            //校验用户名的长度
            //if(!/\w{4,16}/.test(usernameValue))  //用正则表达式检验
            if (usernameValue.length < 4 || usernameValue.length > 16) {
                // alert("用户名不合法!");
                document.querySelector("#name_msg").innerHTML = "用户名不合法";
                flag = false;
            } else {
                document.querySelector("#name_msg").innerHTML = "";//每一次离焦都重新判断,否则一直是不合法
            }

            return flag;//返回一个布尔值判断是否合法
        }

        input.addEventListener('blur', checkUsername);
        //把整个校验的过程提出,用来返回布尔值用于表单提交的判断

        // 校验手机号
        let input2 = document.querySelector("#phone");
        //匿名函数命名
        let checkPhone = () => {
            let phoneValue = input2.value;
            let flag = true;

            //校验手机号的长度
            //if(!/^1[3-9]\d{9}$/.test(phoneValue)) //用正则表达式检验
            if (phoneValue.length != 11) {
                document.querySelector("#phone_msg").innerHTML = "手机号不合法";
                flag = false;
            } else {
                document.querySelector("#phone_msg").innerHTML = "";
            }
            return flag;
        }
        input2.addEventListener('blur', checkPhone)

        // 表单提交时,需要校验整个表单是否合法,如果不合法不让提交
        //JavaScript可以通过event.preventDefault()阻止表单的默认提交事件
        document.querySelector("form").addEventListener("submit", (event) => {
        //event 参数是为了获取事件对象,调用 preventDefault() 方法
        //一定要加括号,这里是调用函数
            if (!checkUsername() || !checkPhone()) {
                alert("用户名或手机号不合法!");
                //阻止表单提交
                event.preventDefault();
            }
        })


    </script>
</body>

</html>

注意:JavaScript中,可以通过事件对象event中的preventDefault() 方法来阻止事件的默认行为,比如阻止表单提交。


这里我们要讲解一下value:

<input type="text">标签里,value属性代表的是输入框当前实际的输入内容

1. 设置初始值

借助value属性,能够为输入框设定默认显示的初始内容。当页面加载完成后,用户会在输入框中看到这个初始值。

<!-- 初始显示"请输入用户名" -->
<input type="text" name="username" value="请输入用户名">

 

对比placeholder: 

 <input type="text" name="username" placeholder="请输入用户名">

 

  • value:是输入框的真实内容,用户可以直接对其进行编辑,并且在表单提交时,这个值会被发送到服务器。
  • placeholder:仅仅是起到提示作用的文本,当用户点击文本框开始输入内容时,它就会自动消失,在表单提交时不会被发送到服务器。

2.表单提交时的作用

当表单提交时,namevalue会以键值对的形式被发送到服务器。要是用户没有对输入框内容进行修改,那么就会提交value属性设置的初始值;要是用户输入了新的内容,就会提交用户输入的值。

在 JavaScript 中,可以通过value属性来获取或修改输入框的当前内容。

正如案例中获取用户名的语句:

let usernameValue = input.value;

虽然表单校验功能,我们基于DOM操作已经完成了,成功的校验了用户名和密码的长度,长度不符合条件,直接提示错误信息,并不允许表单提交,看似非常完美。但是大家可以想一想,对于手机号,是只要11位就可以了吗? 如果出现如下的手机号,是合法的手机号吗?

  • 12209120990

  • 11009120990

  • 1220912abcd

我们发现,上述的字符串,长度都是11位,但是却不是合法的手机号 。因为手机号,是需要符合特定规则的,比如全部都是数字,而且第一位,必须是1,第二位,可以是 3/4/5/6/7/8/9 ,然后后面是9位数字。

那我们应该如何来校验类似于手机号这种,特定规则的字符串呢? 那此时呢,就需要通过正则表达式,来校验了,那接下来,我们就来学习正则表达式。

4.正则表达式

  • 介绍:正则表达式(Regular Expression,也简称为正则),定义了字符串组成的规则。

  • 作用:通常用来验证数据格式、查找替换文本 等。

  • 定义:

        正则表达式字面量(注意不要加引号

const reg1 = /abc/;

         创建正则对象RegExp

const reg2 = new RegExp('abc');

 示例:

 <script>
    let str1 = 'hello World';
    let str2 = '二哈很二o';
    let str3 = 'er哈就是很二o';
    let str4 = '二哈就是很二';

    console.log(/\w+/.test(str1)); //true
    console.log(/\w+/.test(str2)); //true
    console.log(/\w+/.test(str3)); //true
    console.log(/\w+/.test(str4)); //false

    const reg1 = /abc/;
    const reg2 = new RegExp('abc');
    console.log(reg1.test('my name is : abc')); //true
    console.log(reg2.test('my name is : abc')); //true
  </script>
  • 方法:

        test(str):判断指定字符串是否符合规则,符合返回true;不符合返回false。

  • 语法:

    1.普通字符:大多数的字符仅能描述它们本身,这些字符称作普通字符,比如字母和数字。

        2.特殊字符:是一些具有特殊含义的字符,可以极大提高了灵活性和强大的匹配功能。量词:表示要

        3.匹配的字符或表达式的数量。

符号含义
^表示以谁开始
$表示以谁结束
[]表示某个范围内的单个字符,如:[0-9]单个数字字符
.表示任意单个字符,除了换行和行结束符
\w代表单词字符:字母、数字、下划线(_),相当于[A-Za-z0-9_]
\d代表数字字符:相当于[0-9]
\s代表空格(包括换行符、制表符、空格等)
符号含义
?零个或一个
*零个或多个
+一个或多个(至少一个)
{n}n个
{m,}至少m个
{m,n}至少m个,最多n个

 学了正则表达式之后,我们可以将刚刚检验表单中的判定用户名和手机号的代码简化

//校验用户名的长度
if(!/\w{4,16}/.test(usernameValue))
//校验手机号的长度
if (!/^1[3-9]\d{9}$/.test(phoneValue))

5. 模块化

所谓JS模块化,指的是JS提供的一种,将JavaScript程序拆分位若干个可按需导入的单独的模块机制。

优势:提高程序的可复用性、可维护性,提供代码加载和运行的效率。

1.定义一个js文件,命名为check.js,并将检验的过程全部放入到js文件中

2.在html文件中,如果需要用到上述的js代码,直接在script标签中引入该js即可

<!DOCTYPE html>
<html>

<head>
    <title>表单</title>
    <style>
        label {
            display: inline-block;
            width: 80px;
            text-align: right;
            margin-right: 10px;
        }

        input {
            width: 250px;
            padding: 10px;
            border: 1px solid #ccc;
            border-radius: 5px;
            margin-bottom: 10px;
        }

        .btn {
            width: 150px;
        }

        .tip {
            color: #ff0000;
            font-size: 12px;
        }
    </style>
</head>

<body>
    <div>
        <h1>用户注册</h1>
        <form>
            <label for="username">用户名:</label>
            <input type="text" id="username" name="username" placeholder="用户名不能为空且长度在4-16个字符">
            <span class="tip" id="name_msg"></span> <br>

            <label for="phone">手机号:</label>
            <input type="text" id="phone" name="phone" placeholder="手机号不能为空且长度为11位">
            <span class="tip" id="phone_msg"></span>
            <br>

            <input type="submit" value="提交" class="btn">
            <input type="reset" value="重置" class="btn">
        </form>
    </div>


    <script src="./js/check.js"></script>
</body>

</html>

OK,那这是在html中,引入JS文件,可以直接使用 <script src=".."></script> 来引入。 那如果是在一个js文件中,我需要用到另外一个js文件中的方法呢。 那此时该如何实现呢 ?

那在JS中,就给我们提供了模块化导入、导出的操作,我们可以通过 export 关键字,来导出模块。 然后在别的需要用到的地方,通过 import 关键字导入模块。

A. checkFn.js 中定义是校验方法

在变量前面加上 export 代表,我们要将该变量、函数、对象导出为一个模块。别的js中要想使用,就可以 import 导入了。

// export 代表导出该方法
export let checkUsername = () => {
    let flag = true;    //用来标识用户名是否合法
    let usernameValue = document.querySelector("#username").value;

    //校验用户名的长度
    if (!/\w{4,16}/.test(usernameValue)) {
        // alert("用户名不合法!");
        document.querySelector("#name_msg").innerHTML = "用户名不合法";
        flag = false;
    } else {
        document.querySelector("#name_msg").innerHTML = "";
    }

    return flag;
}

export let checkPhone = () => {
    let phoneValue = document.querySelector("#phone").value;
    let flag = true;

    //校验用户名的长度
    if (!/^1[3-9]\d{9}$/.test(phoneValue)) {
        document.querySelector("#phone_msg").innerHTML = "手机号不合法";
        flag = false;
    } else {
        document.querySelector("#phone_msg").innerHTML = "";
    }
    return flag;//true,合法;false,不合法;
}

B. check.js 中定义的是校验的事件监听

那在check.js中需要用到 checkUsername、checkPhone函数,就可以通过 import 关键字将其导入进来。

import {checkUsername as cku, checkPhone} from './checkFn.js'
//as为重新命名,在js导入和导出时都可以重新命名,全文中要一致
// 需求:表单校验--用户名:长度在4-16位;手机号:长度11位
// 分析:JS事件--鼠标离焦事件blur, 表单提交事件submit,, DOM操作
// 校验用户名
// 1.获取dom元素
document.querySelector("#username").addEventListener('blur', cku);

// 校验手机号
document.querySelector("#phone").addEventListener('blur', checkPhone)

// 表单提交时,需要校验整个表单是否合法,如果不合法不让提交
document.querySelector("form").addEventListener("submit", (event) => {
    if (!cku() || !checkPhone()) {
        alert("用户名或手机号不合法!");
        //阻止表单提交
        event.preventDefault();
    }
})

 C. xxx.html 中就是html的基础代码样式

注意:如果我们使用到了 export, import 这种模块化的js,那在通过 <script src="..."></script> 在引入JS文件时,必须指定 type="module" 属性,表名我们使用的是模块化的JS。

<script type="module" src="js/check.js"></script>

如下所示:

<!DOCTYPE html>
<html>

<head>
    <title>表单</title>
    <style>
        label {
            display: inline-block;
            width: 80px;
            text-align: right;
            margin-right: 10px;
        }

        input {
            width: 250px;
            padding: 10px;
            border: 1px solid #ccc;
            border-radius: 5px;
            margin-bottom: 10px;
        }

        .btn {
            width: 150px;
        }

        .tip {
            color: #ff0000;
            font-size: 12px;
        }
    </style>
</head>

<body>
    <div>
        <h1>用户注册</h1>
        <form>
            用户名:
            <input type="text" id="username" name="username" placeholder="用户名不能为空且长度在4-16个字符">
            <span class="tip" id="name_msg"></span> <br>

            手机号:
            <input type="text" id="phone" name="phone" placeholder="手机号不能为空且长度为11位">
            <span class="tip" id="phone_msg"></span>
            <br>

            <input type="submit" value="提交" class="btn">
            <input type="reset" value="重置" class="btn">
        </form>
    </div>

    <!-- 外部脚本 注意:如果js模块化了,导入的时候需要添加type类型为module-->
    <script type="module" src="js/check.js"></script>
</body>

</html>

注意:如果要用模块的js,使用了export,import,一定要保证代码是在服务器运行,而不是在磁盘中打开。

 6.总结

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值