JS事件绑定、事件触发、事件对象、事件委托、节流防抖

        这是以前整理的JavaScript事件的一些基础内容。

一、事件的由来

        随着Web的迅速发展,HTML+CSS的静态页面已经无法满足用户的需求,于是就出现了能让用户与浏览器进行交互的JavaScript,而实现这部分功能的大功臣就是我们本次要讲的——事件。事件是JavaScriptDOM之间交互的桥梁是指用户在浏览器上由于某种行为所执行的操作

  • 事件的分类

UI事件

  • load Web 页面加载完成
  • unload Web 页面正在卸载
  • error JS解析出错或有不存在资源
  • resize 浏览器窗口大小变化
  • scroll 滚动条移动

键盘事件

  • keydown 用户按下按键
  • keyup 用户松开按键
  • keypress 按入了一个字符

鼠标事件

  • click 在一个元素上按下并松开
  • dblclick 在一个元素上连按两下并松开
  • mousedown 在一个元素上按下鼠标按键
  • mouseup 在一个元素上松开鼠标按键
  • mousemove 鼠标移动
  • mouseover 鼠标移入一个元素上
  • mouseout 鼠标从一个元素上移开

焦点事件

  • focus/focusin 元素得到焦点
  • blur/focusout 元素失去焦点

表单事件

  • input 输入框中值发生了变化
  • change 表单元素的值发生了变化
  • submit 用户提交表单
  • cut 剪切了内容
  • copy 复制了内容
  • paste 粘贴了内容

变动事件

  • DOMSubtreeModified 文档发生了变化
  • DOMNodeInserted 一个节点呗插入为另一个节点的直接子节点
  • DOMNodeRemoved 一个节点被从另一个节点中移除
  • DOMNodeInsertedIntoDocument 一个节点被插入为另一个节点的后代
  • DOMNodeRemovedFromDocument 一个节点被从其祖先节点上移除

        这五花八门的各种事件类型,使JavaScript代码变得十分灵活性,给开发人员的设计也提供了更多可能性。

  • 怎么将事件绑定到节点上

        随着时代的发展,不仅事件的种类越来越多,事件与DOM节点的绑定方式也出现了很多种。

DOM0级事件

<a onclick=”alert()”></a>

        这种写法能以最快的速度绑定,不用等到JS运行,但因为现在要求HTML与JS代码的分离,所以大多采用以下形式在JS代码中进行节点与事件的绑定。

element.onclick = function(){}

DOM0的事件具有极好的跨浏览器优势,即兼容性好。

DOM1级事件

        1级DOM标准中并没有定义事件相关的内容,所以没有所谓的1级DOM事件模型。

DOM2级事件

element.addEventListener(‘click’, myFunttion(obj), false)

        这里传入的执行函数不能加小括号,不然JS代码执行到这里的时候就会认为是要执行这个函数,如果要传入参数的话可以使用匿名函数,如下:

element.addEventListener(‘click’, function(){

myFunction(object);

}, false)

        估计有人就要问了,匿名函数虽然好用,但是如果我要移除这个事件该怎么办?我们都知道移除绑定事件可以用node.removeEventListener(‘type’,funName),但需要指定事件类型和所绑函数名,然而匿名函数是没名字的,这时候可以采用以下方法移除事件:

var fun;

btn.addEventListener("click",function(e){

fun=arguments.callee; //arguments.callee指的是本函数

});

function remove(){

btn.removeEventListener("click",fun);

}

DOM3

 

  • 事件流

因为HTML元素总是盒子套盒子,当你在子元素中触发点击事件,同样也是相当于点击了父元素,若是父子都有绑定点击事件,那么事件的顺序触发便产生了事件流。事件流有两种不同的流向:事件冒泡、事件捕获。

事件冒泡

概念:事件从最具体的节点向外传播到最顶层节点(window),这是事件流的默认类型,也被绝大多数浏览器所支持。不是所有的事件都能冒泡,例如:blur、focus、load、unload等。

事件捕获

概念:事件从最顶层(window)的节点向内传播到最具体的节点,在IE8及以下不支持。

在多个节点上同时添加事件冒泡和事件捕获执行顺序

实验见分晓:

grandfather.addEventListener('click',function(){

            console.log('爷节点捕获');

        },true)

        father.addEventListener('click',function(){

            console.log('父节点冒泡');

        },false)

        son.addEventListener('click',function () {

            console.log('子冒泡');

        },false)

        son.addEventListener('click',function () {

            console.log('子捕获');

        },true)

点击子节点:

grandfather.addEventListener('click', function () {

            console.log('爷节点捕获');

        }, true)

        father.addEventListener('click', function () {

            console.log('父节点冒泡');

        }, false)

        son.addEventListener('click', function () {

            console.log('子捕获');

        }, true)

        son.addEventListener('click', function () {

            console.log('子冒泡');

        }, false)

点击子节点:

结论:绑定在点击元素的事件是按照代码的顺序发生的,其他非绑定的元素则是通过冒泡或者捕获的触发。按照W3C的标准,先发生捕获事件,后发生冒泡事件。所以事件的整体顺序是:非目标元素捕获 -> 目标元素代码顺序 -> 非目标元素冒泡。

  • 事件对象

每当事件发生时,如果有指定参数,事件对象会作为匿名封装函数的第一个参数传递进去(自动发生),事件对象中包含一些该事件的有用信息和方法。

function hide(e,object){

e.target /srcElement(IE8以下) //事件的对象

e.type //事件的类型

e.preventDefault(); //阻止默认事件,如超链接跳转

e.stopPropagation(); //阻止事件冒泡/捕获

event.stoplmmediatePropagation() //不仅阻止默认事件还阻止事件流

......

}

var a=document.getElementById('a');

a.addEventListener('click',function(e){

hide(e,obj);

},false);

事件委托

当子元素过多,逐一添加监听器会造成页面流畅度下降,所以利用事件流的特性将事件监听器的工作委托给父元素或祖先元素。

例:需要一个<ul>的每一个<li>点击后都能弹框,如果<ul>中有1000个<li>,那我们也只在<ul>上绑定一个点击事件触发弹框就可以了,而不需要逐一的去给<li>添加事件。

事件节流

高频事件触发,但在n秒内只会执行一次,每次触发事件时,如果当前有等待执行的延时函数,则直接return。

function throttle(fn,delay=100){
    let timer=null    
    return function(){
        if(timer){
            return
        }
        time=setTimeout(()=>{
            fn.apply(this,arguments)
            timer=null
        },delay)lay)
    }
}

事件防抖

触发高频事件后n秒内函数只会执行一次,如果n秒内高频事件再次被触发,则重新计算时间。如果事件在规定的时间间隔内被不断的触发,则调用方法会被不断的延迟。

function debounce(fn,delay=500){
    let timer=null
    return function(){
        if(timer){
            clearTimeout(timer)
        }
        timer=setTimeout(()=>{
            fm.apply(this,arguments)
            timer=null
        },delay)
    }
}

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue和Loadsh在前端开发中非常常用,在前端开发过程中常常遇到需要节流的情况。下面我们将具体介绍Vue和Loadsh对事件节流的实现。 事件是指在短时间内多次触发同一事件,只执行最后一次触发事件。这种现象常见于浏览器不断地触发resize、scroll、mousemove等多种事件。为了避免短时间内多次执行同一事件而导致的浪费资源和卡顿现象,我们通常会采用事件的方式来避免这种情况的出现。 Vue通过@keyup、@keydown、@input等事件方式可以实现事件。例如: <template> <div> <input type="text" v-model="value" @keyup="debounceHandle"/> <div>{{ value }}</div> </div> </template> <script> import debounce from 'loadash/debounce'; export default { data () { return { value: '' } }, methods: { debounceHandle: debounce(function() { console.log('事件'); }, 500) } } </script> 上述代码中,我们使用loadash/debounce函数,这个函数会返回一个debounced函数。在此处,我们将debounced函数到@keyup事件上,设置延迟时间为500毫秒。这样在输入框输入的时候,每次输入之后都会等待500毫秒后执行该函数,确保不会多次执行该函数。 事件节流是指在一段时间内,多次触发同一事件,但只执行一次函数。相比于事件事件节流触发事件按照一规律分为多个时间段,在一个时间段内只执行一次函数。 Vue和Loadsh的throttle函数可以实现事件节流。例如: <template> <div> <input type="text" v-model="value" @keyup="throttleHandle"/> <div>{{ value }}</div> </div> </template> <script> import throttle from 'loadash/throttle'; export default { data () { return { value: '' } }, methods: { throttleHandle: throttle(function() { console.log('事件节流'); }, 500) } } </script> 上述代码中,我们使用loadash/throttle函数,这个函数会返回一个throttled函数。在此处,我们将throttled函数到@keyup事件上,设置间隔时间为500毫秒。这样在输入框输入的时候,在500毫秒时间内只执行一次函数。 综上所述,事件事件节流是前端开发中非常常用的技术,通过Vue和Loadsh的配合可以轻松实现事件事件节流。在实际开发过程中,需要根据具体情况选择使用节流技术。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值