事件处理、事件对象、事件的分类、正则表达式

一.事件处理

1.基本概念

(1)事件:JavaScript可以侦测到的行为(用户在页面上进行的某种操作)

页面加载(浏览器打开页面)、单击鼠标、鼠标进入某个区域、焦点、键盘

(2)事件处理程序:用户进行某种操作以后所运行的JavaScript程序段

(3)事件驱动式:当事件发生后才去执行相应的程序

(4)事件流:事件发生时,会在发生事件的元素节点与DOM树根节点之间按照特定的顺序进行传播,这个事件传播的过程就是事件流。

(5)在web中对事件流的解决方案:

a.事件捕获:网景公司Netscape。事件流传播顺序应该是从DOM树的根节点到发生事件的元素节点

b.事件冒泡:微软公司。事件流传播的顺序应该是从发生事件的元素节点到DOM树的根节点

冒泡的前提是:父级也定义了相应的事件。当子元素与父元素有相同的事件时,当子元素被触发时父元素也会被触发冒泡机制

c.W3C的事件流处理:在事件发生阶段采用捕获方式(此时不处理),在时间处理阶段采用冒泡

(6)事件捕获的实现:

addEventListener(事件名,事件处理程序,事件处理方式)

事件名:click、change、load、mousedown...

事件处理方式:(true--表示采用事件捕获方式,false:采用事件冒泡方式)

例1:

<body>
    <div id="myDiv" style="width: 100px;height:200px;background:red;">点击</div>
    <script>
        window.onclick = function(){
            alert('window')
        }
        document.onclick = function(){
            alert('document')
        }
        document.documentElement.onclick = function(){
            alert('html')
        }
        document.body.onclick = function(){
            alert('Body')
        }
        document.getElementById('myDiv').onclick = function(e){//e:事件对象event,只要有事件发生都会生成一个event对象
            alert('myDiv')
            if (window.event) {
                // cancelBubble取消冒泡
                window.event.cancelBubble = true //早期浏览器IE6-8
            }else{
                // 停止冒泡stopPropagation()
                e.stopPropagation()//标准浏览器采用的方法
            }
        }
    </script>
</body>

例2: 

<style>
    #parent{
        width: 200px;
        height: 200px;
        background-color: red;
    }
    #child{
        width: 100px;
        height: 100px;
        background-color: pink;
    }
</style>
<body>
    <div id="parent">
        <div id="child"></div>
    </div>
    <script>
        // 冒泡方式
        document.getElementById('parent').addEventListener('click',function(){
            alert('parent被触发')
        },true)
        document.getElementById('child').addEventListener('click',function(e){
            alert('child被触发')
            if (window.event) {
                window.event.cancelBubble = true
            } else {
                e.stopPropagation()
            }
        },true)
    </script>
</body>

2.事件的绑定方式:

 (1)行内绑定式               <标签名 事件名=‘事件处理程序’></标签名>

(2)动态绑定式                DOM对象名.事件名 = 事件处理程序

注意:‘行内绑定式’和‘动态绑定式’的区别

异:a.‘行内绑定式’中事件名作为标签的属性,‘动态绑定式’中事件名作为DOM对象的属性

       b.‘行内绑定式’的事件处理程序中的this代表的是window对象,‘动态绑定式’的事情处理程序中的this代表的是触发事件的DOM对象

同:一个DOM对象的同一个事件只能有一个事件处理程序

(3)事件监听式:可以给DOM对象的同一个事件绑定多个事件处理程序

DOM对象.addEventListener(type,callback,[capture])//标准浏览器

DOM对象.attachEvent(type,callback,[capture])//早期IE浏览器

3.删除事件绑定                DOM对象.removeEventListener(type, callback);

<body>
    <button id="btn_submit">提交</button>
    <button id="btn_cancel">取消</button>
    <script>
        let btn = document.getElementById('btn_submit')
        function f1(){
            alert(1)
        }
        btn.addEventListener('click',f1)
        function f2() {
            alert(2)
        }
        btn.addEventListener('click',f2)
        function f3() {
            alert(3)
        }
        btn.addEventListener('click',f3)
        let cancel = document.getElementById('btn_cancel')
        cancel.addEventListener('click',function(){
            btn.removeEventListener('click',f1)//删除click事件上绑定的f1函数
            btn.removeEventListener('click',f3)
        })
    </script>
</body>

二.事件对象

1.来源:当事件发生时,都会产生一个事件对象(event对象)

2.作用:通过事件对象可以了解与事件相关的信息(DOM对象、事件的类型...)

3.获取事件对象:

(1)早期的IE浏览器

(2)标准浏览器:将一个event对象直接传入事件处理程序中

4.常用属性:

(1)type:当前事件类型

(2)target:返回触发此事件的元素(事件的目标节点)

(3)currentTarget:返回其事件监听器触发该事件的元素

(4)bubbles:事件是否是冒泡类型

<body>
    <button id="btn_test">测试事件对象</button>
    <br><br>
    <div id="div1" style="width: 100px;height:100px;background-color: red;"></div>
    <script>
        /* document.getElementById('btn_test').addEventListener('click',function(e){//e:事件对象
            console.log('事件对象',e)
        })
        document.getElementById('div1').addEventListener('click',function(e){
            console.log('事件对象',e)
        }) */
        /* document.getElementById('btn_test').addEventListener('click',function(e){//e:事件对象
            console.log('事件类型',e.type)
        })
        document.getElementById('div1').addEventListener('mousemove',function(e){
            console.log('事件对象',e.type)
        }) */
        /* document.getElementById('btn_test').addEventListener('click',function(e){//e:事件对象
            console.log('事件元素',e.target)
        })
        document.getElementById('div1').addEventListener('mousemove',function(e){
            console.log('事件元素',e.target)
        }) */
        document.getElementById('btn_test').addEventListener('click', function (e) {//e:事件对象
            console.log('事件类型', e.currentTarget)
        })
        document.getElementById('div1').addEventListener('mousemove', function (e) {
            console.log('事件是否冒泡', e.bubbles)
        })
    </script>
</body>

5.常用函数:

(1)stopPropagation():阻止事件冒泡

(2)preventDefault():阻止默认行为

<body>
    <button id="btn_test">测试事件对象</button>
    <br><br>
    <div id="div1" style="width: 100px;height:100px;background-color: red;"></div>
    <br><br>
    <a href="https://www.bilibili.com" id="click_a">进入B站</a>
    <script>
        document.getElementById('click_a',function(e){
            e.preventDefault()
        })
    </script>
</body>

三.事件的分类

1.页面事件

(1)load:页面加载事件。用于body内所有标签都加载完成后才触发

(2)unload:用于页面关闭时触发,经常用于清除变量,避免内存的泄露

2.焦点事件

(1)focus:当获取焦点时触发

(2)blur:失去焦点时触发

<style>
    .true{
        color: greenyellow;
    }
    .false{
        color: red;
    }
</style>
<body>
    <div>
        用户名:<input type="text" id="userName"><span id="nameInfo"></span><br>
        密码:<input type="password" id="pwd"><span id="pwdInfo"></span>
    </div>
    <!-- 练习:表单验证 -->
    <script>
        // 获取用户名
        let users = document.getElementById('userName')
        // 失去焦点
        users.addEventListener('blur',function () {
            // 获取用户名后面的span
            let span1 = document.getElementById('nameInfo')
            if ('admin' === users.value) {
                // 删除错误的类名
                span1.classList.remove('false')
                span1.innerHTML='用户名正确'
                // 添加样式
                span1.classList.add('true')
            }else{
                // 删除正确的类名
                span1.classList.remove('true')
                span1.innerHTML='请重新输入'
                span1.classList.add('false')
            }
        })
        let passwd = document.getElementById('pwd')
        passwd.addEventListener('blur',function(){
            let span2 = document.getElementById('pwdInfo')
            if (this.value.length>=6 && this.value.length <=16 &&users.value === 'admin') {
                span2.classList.remove('false')
                span2.innerHTML='密码正确'
                span2.classList.add('true')
            }else{
                span2.classList.remove('true')
                span2.innerHTML='请重新输入'
                span2.classList.add('false')
            }
        })
    </script>
</body>

3.鼠标事件

(1)click:鼠标单击

(2)dblclick:鼠标双击

(3)mouseover:鼠标移入

(4)mouseout:鼠标移出

(5)change:当内容发生改变时触发--多用于input、select

<body>
     <select name="" id="change">
        <option value="%">请选择</option>
        <option value="red">红玫瑰</option>
        <option value="green">绿光</option>
        <option value="pink">Hello Kitty</option>
     </select>  
     <script>
        let select = document.getElementById('change')
        select.addEventListener('change',function(){
            document.body.style.backgroundColor = this.value
        })
     </script> 
</body>

(6)mousedown:当按下任意鼠标按键时触发

(7)mouseup:当释放任意鼠标按键时触发

(8)mousemove:在元素内当移动鼠标时持续触发

4.在鼠标事件中,鼠标的位置信息的获取

(1)clientX:鼠标指针位于浏览器页面当前窗口可视区的水平坐标(坐标X轴)

(2)clientY:鼠标指针位于浏览器页面当前窗口可视区的垂直坐标(Y轴坐标)

(3)pageX:鼠标指针位于文档的水平坐标(坐标X轴)

(4)pageY:鼠标指针位于文档的垂直坐标(Y轴坐标)

(5)screenX:鼠标指针位于屏幕的水平坐标(坐标X轴)

(6)screenY:鼠标指针位于屏幕的垂直坐标(Y轴坐标)

<script>
    window.addEventListener('mousemove',function(e){
        console.log('e.clientX:',e.clientX)
        console.log('e.clientY:',e.clientY)
    })
    window.addEventListener('mousedown',function(e){
        console.log('e.pageX:',e.pageX)
        console.log('e.pageY:',e.pageY)
        console.log('e.screenX:',e.screenX)
        console.log('e.screenY:',e.screenY)
    })
</script>

强调:事件对象的兼容性处理

(一)早期的IE浏览器版本获取事件对象的方法:window.event

标准浏览器获取事件对象的方法:event

DOM对象:addEventListener(‘事件名称’,function(e)){

                           let/var 变量 = e || window.event

                    }

  (二)早期的IE浏览器对事件对象的pageX和pageY

var pageX = event.pageX || event.clientX + document.documentElement.scrollLeft;

var pageY = event.pageY || event.clientY + document.   documentElement.scrollTop;

练习:当鼠标在浏览器窗口中移动时,在鼠标指针旁边显示指针的坐标

<style>
    #box{
        position: absolute;
    }
</style>
<body>
    <div id="box"></div>
    <script>
        window.onload = function(){
            // 获取div
            let div = document.getElementById('box')
            // 给document绑定mousemove事件
            document.onmousemove = function (event) {
                let left_position = event.clientX + 'px'
                let top_position = event.clientY + 'px'
                div.style.left = left_position
                div.style.top = top_position
                div.innerHTML = left_position +',' + top_position
            }
        }
    </script>
</body>

5.键盘事件:用户在使用键盘时触发

(1)keypress:键盘上按键按下时触发,不包含非字符按键(功能键)。保存的是按键的ASCII值

(2)keydown:键盘上按键按下时触发

(3)keyup:键盘按键弹起时触发

keydown和keyup保存的是按键的虚拟键码

<script>
    document.addEventListener('keypress',function(e){
        console.log('事件对象',e)
        console.log('',e.keyCode)
    })
    document.addEventListener('keydown',function(e){
        // // console.log(e.keyCode)
        // // if (e.altKey) {
        // //     alert('Alt')
        // // }
        // // if(e.ctrlKey){}
        // // if (e.shiftKey) {}
        // console.log(e.code)
        // console.log(e.key)

    })
    document.addEventListener('keyup',function (e) {
        console.log('keyup:',e.key)//key保存的是小写字母
        console.log('keyCode:',e.keyCode)//keyCode保存的是ASCII值
    })
</script>

6.表单事件:操作表单时触发

(1)submit:当表单提交时触发

(2)reset:当表单重置时触发

四.正则表达式

1.什么是正则表达式?

(1)是描述字符串组成结构的语法规则

(2)是用于匹配字符串中字符组合的模式

(3)是一个对象

2.特点

(1)非常灵活

(2)逻辑性非常强

(3)以非常简单的方式达到对字符串进行复杂的控制

3.创建正则表达式

(1)使用字面量                var 变量 = /表达式/

(2)使用RegExp构造函数        var 变量名 = RegExp(/表达式/)

            或                                    var 变量名 = new RegExp(/表达式/)

4.正则表达式的使用

(1)test()方法:返回Boolean值。true:符合正则规则;false:不符合

                正则对象.test(被验证的字符串)

(2)模式修饰符:基本语法/表达式/[switch]

switch:表示模式修饰符,是可选的,可以对正则进一步的设置

                g:全局匹配                i:忽略大小写

(3)边界符:

^:表示匹配行首的文本(以...开头

$:表示匹配行尾的文本(以...结尾

(4)预定义字符:

.除了'\n'之外的任意单个字符

\d:匹配0-9之间的任意数字。等价于[0-9]

\D匹配0-9以外数字。等价于[^0-9]

\w:匹配任意字母、数字、下划线。等价于[a-zA-Z0-9]

\W:除所有字母、数字、下划线以外的字符,相当于[^a-zA-Z0-9]

\b单词分界符

\s匹配空格(包括换行符、空格、制表符等),相当于[\t\r\n\v\f]

match(正则表达式)方法:是string对象的方法,用来截取符合正则表达式规则的子串,返回值是数组

强调:转义字符'\',若要输出反斜杠,要使用连续两个'\\'

<script>
    // var reg1 = /123/  //串长度为3
    // var reg2 = RegExp(/111/)
    // var reg3 = new RegExp(/222/)
    // let s1 = '123'
    // console.log(reg1.test(s1))

    var reg = /abc/gi  //全局,忽略大小写
    console.log(reg.test('abc'))//true
    console.log(reg.test('ABC'))//false
    var reg1 = /^abc/gi
    console.log(reg1.test('ABC'))//true
    var reg2= /abc$/gi
    console.log(reg2.test('ABC'))//true
    var reg3= /^abcabc$/gi
    console.log(reg2.test('AbcABc'))//true

    var str = 'good idea 123 463'
    var reg4 = /\s../gi //匹配空格开始两个任意单个字符
    let s2 = str.match(reg4)
    console.log(s2)//['id','12','46']

    // 将字符串中所有的特殊字符匹配出来
    var str1 = '^abc\\1.23*edf$'
    var reg5 = /\.|\$|\*|\^|\\/gi
    let t = str1.match(reg5)
    console.log(t)// ['^','\\','.','*','$']
</script>

(5)字符范围示例

[cat]:匹配字符集合中的任意一个字符c、a、t

[^cat]:匹配除c、a、t以外的字符

[A-Z]:匹配字母A-Z范围内的字符

[^a-z]:匹配字母a-z范围外的字符

[a-zA-Z0-9]:匹配大小写字母和0-9范围内的字符

[\u4e00-\u9fa5]:匹配任意一个中文字符

字符组合:如果允许用户输入英文字母(不区分大小写)、数字、短横线-、下划线_的正则情况。

<style>
    .success{
        color: green;
    }
    .fail{
        color: red;
    }
</style>
<body>
    用户名:<input type="text" id="user"><span ></span>
    <br/><br/>
    密码:<input type="password" id="pwd">
    <script>
        var reg = /^[a-zA-Z0-9_-]{6,16}$/
        let user= document.getElementById('user')
        let span = document.querySelector('span')
        user.onblur = function () {
            if (reg.test(user.value)) {
                document.querySelector('span').classList.remove('fail')
                document.querySelector('span').innerHTML = '用户名正确'
                document.querySelector('span').classList.add('success')
            }else{
                document.querySelector('span').classList.remove('success')
                document.querySelector('span').innerHTML = 'error'
                document.querySelector('span').classList.add('fail')
            }
        }
    </script>
</body>

(6)量词符

{m,n}:表示{}之前的数字可以出现m-n次

{n}:表示{}之前的字符可以出现n次

{n,}:匹配{}前面的字符最少n次

?:匹配?之前的字符零次或一次

<script>
    let reg1 = /hi?t/
    let str1 = 'hiit'
    console.log(reg1.test(str1))
</script>

注意:exec(字符串):是正则表达式对象的方法。返回值类型是数组

<script>
    let reg1 = /hi?t/
    let str1 = 'hiit'
    let arr = reg1.exec(str1)
    console.log(arr)
</script>

+:匹配+前面的字符一次或多次

*:匹配*前面的字符零次或多次

(7)括号字符:改变限定符的范围

a.改变限定符范围之catch|er                        匹配结果:catch、er

b.改变限定符范围之cat(ch|er)                匹配结果:catch、cater

c.分组:

                                分组        abc{2}  c出现2次

                                分组后        a(bc){2}  bc出现2次

<script>
    let reg = /catch|er/
    let s1 = 'catch1'
    console.log(reg.test(s1))//true
    console.log(reg.exec(s1))//['catch', index: 0, input: 'catch1', groups: undefined]
    s1 = 'catc'
    console.log(reg.test(s1))//false
    console.log(reg.exec(s1))//null
    s1 = 'er'
    console.log(reg.test(s1))//true
    console.log(reg.exec(s1))//['er', index: 0, input: 'er', groups: undefined]
</script>

5..捕获与非捕获

(1)捕获:使用小括号可以进行分组,当小括号后面由量词符时,就表示对整个组进行操作

<script>
    let reg1 = /(\d)(\d)(\d)(\d)/ //表示4位数字,每位都是0~9之间
    let str1 = '1234'
    console.log(reg1.test(str1))
    console.log(reg1.exec(str1))//(5) ['1234', '1', '2', '3', '4', index: 0, input: '1234', groups: undefined]
</script>

(2)进行字符串的替换:replace结合正则表达式实现  

<script>
    let reg2 = /(\w+)\s(\w+)/
    let str2 = 'Regular Capture';
    // console.log(reg2.exec(str2))
    let newStr = str2.replace(reg2,'$2 $1')
    console.log(newStr)//Capture Regular
        
    reg2 = /(\w+)\s(\w+)\s(\w+)/
    str2 = 'Regular Capture hi'
    newStr = str2.replace(reg2,'$3 $2 $1')
    console.log(newStr)//hi Capture Regular
</script>

6.贪婪匹配与懒惰匹配

(1)贪婪匹配:匹配尽可能多的字符。是正则表达式的默认匹配方式

(2)懒惰匹配:匹配尽可能少的字符。通过?来实现

<script>    
    var str = 'wsbWEBWebwEB'
    var reg1 = /w.*b/gi   //贪婪匹配
    console.log(reg1.exec(str))
    var reg2 = /w.*?b/gi  //懒惰匹配  表示只要有一次匹配成功即可,不会继续进行匹配
    console.log(reg2.exec(str))
</script>

7.优先级                  一级:\  转义字符

                                二级:()、[]

                                三级:*、+、?、{n}、{n,}、{m,n}

                                四级:^、$、\任何元字符、任何字符

示例:验证身份证号

身份证的正则表达式为:

【过去】 /(^\d{15}$)|(^\d{17}([0-9]|X)$)/

【现在】/^[1-9]\d{5}(19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/

<style>
    .success{
        color: greenyellow;
    }
    .fail{
        color: red;
    }
</style>
<body>
    身份证<input type="text" id="id_card"><span></span>
    <script>
        let idCard = document.getElementById('id_card')
        // 过去的身份证证号
        let num = /(^[1-9]\d{14}$)|(^[1-9]\d{16}([0-9]|X)$)/
        // 最新的身份证号
        let num1 = /^[1-9]\d{5}(19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/
        idCard.onblur = function(e){
            // 过去      num.test(idCard.value)
            // 现在      num1.test(idCard.value)
            if (num1.test(idCard.value) ) {
                document.querySelector('span').classList.remove('fail')
                document.querySelector('span').innerHTML = '输入正确'
                document.querySelector('span').classList.add('success')
            }else{
                document.querySelector('span').classList.remove('success')
                document.querySelector('span').innerHTML = '输入错误'
                document.querySelector('span').classList.add('fail')
            }
        }
    </script>
</body>

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值