Javascript事件

一、JavaScript事件简介:

什么叫事件:当我们点击一个按钮的时候,会弹出一个对话框。在JavaScript中,“点击”这个事情就看做一个事件。“弹出对话框”其实就是我们在点击事件中做的一些事情。

事件应该分为三部分:

事件源:触发谁的事件

事件类型:这个事件是干什么的,是点击呢,还是移动呢等等

事件处理函数:事件过程做的一些事情

 二、事件对象event:

每触发一个事件都会生成事件对象

事件对象包含对事件的描述信息:你触发一个点击事件的时候,你点在哪个位置了,坐标是多少

                                                        你触发一个键盘事件的时候,你按的是哪个按钮

获取事件对象:在每一个时间处理函数的行参位置,默认第一个就是事件对象

 

IE兼容写法:

e=e || window.event

三、点击事件的光标坐标点获取

每个点击事件的坐标点都不是一对,因为有一个相对的坐标系

相对事件源(你点击的元素),相对页面,相对浏览器窗口

相对事件源(你点击的元素)offsetX,offsetY:

是相对于你点击的元素的边框内侧开始计算

offsetX和offsetY

 相对于浏览器窗口(clientX,clientY)

是相对于浏览器窗口来计算的,不管你页面滚动到什么情况,都是根据窗口来计算坐标

clientX和clientY

 相对于页面(pageX和pageY):

是相对于整个页面的坐标点,不管有没有滚动,都是相对于页面拿到的坐标点

pageX和pageY

 四、常见的事件:

大致分为几类,浏览器事件/鼠标事件/键盘事件/表单事件/触发事件

浏览器事件:load:页面全部资源加载完毕   scroll:浏览器滚动的时候触发   resize:页面大小事件

鼠标事件:click:点击事件   dbclick:双击事件  contextmenu:右键点击事件   mousesown:鼠标左键按下事件  mouseup:鼠标左键抬起事件  mousemove:鼠标移动事件  mouseout:鼠标移出事件   mouseover:鼠标移入事件  mouseenter:鼠标移入事件   mouseleave:鼠标移出事件

mouseover与mouseenter区别

 1、onmouseover、onmouseout:鼠标经过时自身触发事件,经过其子元素时也触发该事件;(父亲有的东西,儿子也有) ,支持冒泡
2、onmouseenter、onmouseleave:鼠标经过时自身触发事件,经过其子元素时不触发该事件。(父亲的东西就是父亲的,不归儿子所有) ,不支持冒泡

键盘事件:

keyup:键盘抬起事件

keydown:键盘按下事件

keypress:键盘按下再抬起事件

表单事件:

change:表单内容改变事件

input:表达内容输入事件

submit:表单内容提交事件

触摸事件:touchstart:触摸开始事件

                  touchend:触摸结果事件

                   touchmove:触摸移动事件

五、事件

鼠标事件:

鼠标移入移出改变样式

 

表单提交事件onsubmit

html:  <div class="container">
        <form id="loginForm" action="#" method="get" autocomplete="off">
            <div class="user-wrap">
              <label for="username">用户名: </label>
              <input type="text" name="username" id="username" />
            </div>
       
            <div class="psw-wrap">
              <label for="password">密&nbsp;&nbsp;&nbsp;码: </label>
              <input type="password" name="password" id="password" />
            </div>
      
            <div class="btn-wrap">
              <input type="submit" value="提交" />
              <input type="reset" value="重置" />
            </div>
          </form>
    </div>
 js:window.onload = function(){
    const userNameEle = this.document.querySelector("#username");
  
    const passwordEle = this.document.querySelector("#password");
    const passWord = passwordEle.value;
 
    const userWrap = document.querySelector(".user-wrap");
    const  userInputEle = this.document.querySelector("#username");
    //事件处理
    userNameEle.onblur = function(){
        const userName = userNameEle.value;
        if(userName == ""){
            if(!userInputEle.nextElementSibling){
                const spanEle = document.createElement("span");
                const spanText = document.createTextNode("用户名不能为空!");
                spanEle.appendChild(spanText);
                spanEle.style.color = "red";
                spanEle.style.fontSize = "12px";
                userWrap.appendChild(spanEle);
            }
           
        }else{
            if(userInputEle.nextElementSibling){
                userWrap.removeChild(userInputEle.nextElementSibling);
            }
        }
    }
}

css:* {
    padding: 0;
    margin: 0;
    font-size: 14px;
}
 
body {
    background: rgba(104, 117, 104, .5);
    position: relative;
    height: 100vh;
}
 
.container {
    width: 600px;
    height: 400px;
    background-color: rgba(130, 64, 192, .4);
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%,-50%);
    border-radius: 30px;
    display: flex;
    align-items: center;
    justify-content: center;
    
    form{
        line-height: 60px;
        width: 100%;
        padding: 0 30px;
 
        .user-wrap{
            display: flex;
            height: 40px;
            margin: 30px 0;
            label{
                color: white;
                font-size: 20px;
                line-height: 40px;
                margin-right: 10px;
            }
            input{
                flex: 1;
            }
        }
        .psw-wrap{
            display: flex;
            height: 40px;
            margin-bottom: 20px;
            input{
                flex: 1;
            }
            label{
                color: white;
                font-size: 20px;
                line-height: 40px;
                margin-right: 10px;
               
            }
        }
        .btn-wrap{
            display: flex;
            justify-content: center;
            input{
                width: 100px;
                height: 50px;
                background-color: rgb(60, 60, 145);
                color: white;
                outline: none;
                border: none;
                margin-right: 10px;
                border-radius: 10px;
                cursor: pointer;
                &:hover{
                    background-color: rgb(67, 150, 67);
                }
            }
           
        }
    }
}

表单提交项目中常用方式:

 

 内容转变事件onchange

焦点事件:失去焦点onblur

                   获取焦点onfocus

键盘事件:

只给能在页面上选中的元素(表单元素)和document来绑定键盘事件

注:不能给页面上一个div元素,设置键盘事件的

 确定按键:我们的键盘上每一个按键都有一个自己独立的编码,我们就是靠这个编码来确定我们按下的是哪个按键的,我们通过事件对象.keyCode或者事件对象.which来获取,为什么要有两个呢,是因为FireFox2.0不支持keycode所以要which

常见的键盘码:8:删除键(delete)9:制表符(tab)等等

 组合按键:

组合按键最主要的就是alt/shift/ctrl三个按键

在我们点击某一个按键的时候判断一下这三个按键有没有按下,有就是组合了,没有就是没组合

 

 六、事件绑定方式:

事件属性DOM0:

把事件写在标签的属性里面:

好处:大家都会,几乎所有的浏览器都支持

坏处:夹杂在HTML文件中,代码不简洁;这种事件写法效率不高‘不符合“行为,样式,结构”相分离

<input type="button" οnclick="alertMessage()"value="按钮">

事件赋值式DOM0:

缺点:只能给一个元素注册一个事件,绑定一个事件,后一个会覆盖前一个

好处:符合“行为,样式,结构”想分离;便于操作当事对象;方便读取事件对象

 当你点击的时候,只会执行第二个,第一个就没有了

事件监听DOM2:

addEventListener:非IE 7 8下使用

语法:元素.addEventListener('事件类型',事件处理函数,冒泡还是捕获)

当你点击div的时候,两个函数都会执行,并且会按照你注册的顺序执行

先打印(我是第一个事件)再打印(我是第二个事件)

注意:事件类型的时候不要写on,点击事件就是click,不是onclick

attachEvent:IE7 8 下使用:

语法:元素.attEvent('事件类型',事件处理函数)

 当你点击div的时候,两个函数都会执行,并且会按照你注册的顺序倒序执行

先打印(我是第二个事件)再打印(我是第一个事件)

注意:事件类型的时候要写on,点击事件onclick

两种写法的去区别;

注册事件的时候事件类型参数的写法

addEventListener:不用写on

attachEvent:要写on

参数个数:

addEventListener:一般是三个常用参数

attachEvent:两个参数

执行顺序:

addEventListener:顺序注册,顺序执行

attachEvent:循序注册,倒序执行

适用浏览器:

addEventListener:非IE 7 8的浏览器

attachEvent:IE 7 8浏览器

七、事件的执行机制

事件的传播:

思考:点击红色区域会不会触发粉红色区域?

 就像上面这张图片一样,我们点击在红色盒子身上的同时,也点击在了粉色盒子上,这个是既定的事实,那么两个盒子的点击事件都会触发,这个叫做事件的传播

当元素触发一个事件的时候,其父元素也会触发相同的事件,父元素的父元素也会触发相同的事件

就像上面的图片一样,点击红色盒子上的时候,会触发红色盒子的点击事件,也是点击在了粉色盒子上,也会触发粉色盒子的点击事件,也是点击了body上,也会触发body的点击事件,也是点击在了html上,也会触发html的点击事件,也是点击在了document上,也会触发document的点击事件,也是点击在了window上,也会触发window的点击事件,也就是说,页面上任何一个元素触发事件,都会一层一层最终导致window的相同事件触发,前提是各层级元素得有注册相同的事件,不然不会触发。

在事件传播的过程中,有一些注意的点:只会传播同类事件,只会从点击元素开始按照html的结构逐层向上元素的事件会被触发,内部元素不管有没有该事件,只要上层元素有该事件,那么上层元素的事件就会被触发。

事件传播的方向:

事件确实会从自己开始,到window的所有相同事件都会触发

是因为我们点在自己身上,也确实逐层的点在了直至window的每一个元素身上

但是到底是先点自己身上,还是先点在了window身上呢?

先点在自己身上,就是先执行自己的事件处理函数,逐层向上最后执行window的事件处理函数

反之,则是先执行window的事件处理函数,逐层向下最后执行自己的事件处理函数

目标:你是点击在哪个元素身上了,那么这个事件的目标是就是什么

事件冒泡:

就是从事件目标的事件处理函数开始,依次向上,直到window的事件处理函数触发

特点:事件传播方向,由内而外

事件捕获:

就是从window的事件处理函数开始,依次向内,只要事件目标的事件处理函数执行,也就是从上向下的执行事件处理函数

事件原型图:

 实现:事件捕获和事件冒泡

addEventListener的第三个参数决定了是事件捕获还是事件冒泡

true:表示注册的事件在捕获阶段触发

false:表示注册的事件在冒泡阶段触发-----默认值

事件处理三个阶段:

事件的处理过程主要有三个阶段:捕获阶段,目标阶段,冒泡阶段;

 W3C:任何事件发生时,先从顶层开始进行事件捕获,直到事件触发到达事件源,再从事件源向上进行事件捕获(事件冒泡)。

标准浏览器:addEventListener("dlick",function,"true")方法,若第三个参数为true,则采用事件捕获。若false,则采用事件冒泡。

IE浏览器只支持事件冒泡,不支持事件捕获,所以它不支持addEventListener("click",function,"true")方法,所以ie浏览器使用ele.attachEvent("click",doSomething).

事件传播的阻止方法:

在W3C中,使用stopPropagation()方法

在IE下使用cancelBubble=true方法

事件目标对象target:

target这个属性是事件对象里面的属性,表示你点击的目标,当你触发点击事件的时候,你点击在哪个元素上,target就是哪个元素,这个target也不兼容,在IE下要使用srecElement

 target与currTarget属性

 当我点击哪个元素时,event.target返回的是点击的元素节点

event.currentTarget返回的是绑定事件的元素

阻止事件传播:

e.stopPerpagation()标准浏览器

e.canceBubble=true IE低版本

兼容性写法:

if(e.stopPropagation){

e.stopPropagation()

}else{

e.canceBubble=true

}

或者e.stopPropagation?e.stopPropagation:e.canceBubble=true

事件委托:

这个时候,当我们点击li的时候,可以触发ul的点事件,并且在事件内部,我们也可以拿到你点击的到底是ul还是li,这个时候,我们就可以把li的事件委托给ul来做

 为什么要用事件委托:

 事件委托的好处:

减少事件绑定的数量,对后来动态创建的元素依然有效,解决动态添加的元素节点无法绑定的问题,减少事件的冗余绑定,节约事件资源。

缺点;事件委托基于冒泡,对于不冒泡的事件不支持。层级过多,冒泡过程中,可能会被某层阻止掉。理论上委托会导致浏览器频繁调用处理函数,虽然很可能不需要处理。所以建议就近委托,比如在table上代理td,而不是在document上代理td。

把所有事件都用代理就可能会出现事件误判。比如,在document中代理了所有button的click事件,另外的人在引用该js时,可能不知道,造成单击button触发两个click事件。

八、默认行为;

默认行为,就是不用我们注册,它自己就存在的事情,比如我们点击鼠标右键的时候,会自动弹出一个菜单,比如我们点击a标签的时候,我们不需要注册点击事件,他自己就会跳转页面

这些不需要我们注册就能实现的事情,我们叫做默认行为

阻止默认行为:

有的时候,我们不希望浏览器执行默认事件

比如我给a标签绑定了一个点击事件,我点击你的时候希望你能告诉我你的地址是什么,而不是直接跳转链接,那么我们就要把a标签原先的默认事件阻止,不让他执行默认事件

两个方法来阻止默认事件 e.preventDefault():非IE使用

e.returnValue=false:IE使用

阻止默认事件的时候也要写一个兼容的写法:

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值