JavaScript常用事件讲解

2023-11-18

声明:本人的所有博客皆为个人笔记,作为个人知识索引使用,因此在叙述上存在逻辑不通顺、跨度大等问题,希望理解。分享出来仅供大家学习翻阅,若有错误希望指出,感谢!

事件流

事件流描述的是从页面接收事件的顺序

事件冒泡

  • 事件开始由最具体的元素接收,然后逐级向上传播到较为不具体的节点

事件捕获

  • 事件开始由最不具体的元素接收,然后逐级向下传播到最具体的节点
  • 很少有人使用事件捕获,可以放心使用事件冒泡

DOM事件流

  • DOM2级事件规定事件流包括三个阶段:事件捕获阶段、处于目标阶段、事件冒泡阶段
  • 事件捕获为截获事件提供了机会,然后是实际的目标接收到事件,最后一个阶段是冒泡阶段,可以在这个阶段对事件做出相应
  • 在DOM事件流中,实际的目标在捕获阶段不会接收到事件
    • 多数支持DOM事件流的浏览器都实现了一种特定的行为:即使规范明确要求捕获阶段不会涉及事件目标,但浏览器都会在捕获阶段触发事件对象上的事件,结果就是:有两个机会在目标对象上操作事件

事件处理程序

相应某个事件的函数叫做事件处理程序,事件处理程序名字以“on”开头

HTML事件处理程序

<标签名 事件名="JavaScript代码">
例如:	<input type="button" value="Click me" onclick="alert(value)">
  • 此处JavaScript代码是一段字符串,故其中不可出现双引号,可用单引号代替,也不能出现未经转义的HTML语法字符
  • 此处JavaScript代码中也可以调用页面其他地方定义的脚本
  • 事件处理程序的代码在执行时,有权访问全局作用域中的任何代码
  • 此处JavaScript代码实际上是一个动态函数,该动态函数使用with为自己拓展作用域
function(){
    with(document){		//因此有权访问全局作用域中的任何代码
        with(this){
            …………
        }
    }
}
//如果当前元素是一个表单元素,则作用域还会包含访问表单元素的入口
function(){
    with(document){
        with(this.form){	//父元素
            with(this){
                …………
            }
        }
    }
}

缺点:

  • 存在时差问题,若html元素一出现就触发相应事件,此时事件处理程序有可能不具备运行条件
  • 在不同浏览器中会导致不同的结果
  • HTML与JavaScript代码紧密耦合

DOM0级事件处理程序

每个元素(包括window和document)都有自己的事件处理属性,这些属性通常全部小写,将这种属性的值设置为一个函数,就能指定事件处理程序

//以点击按钮为例
var btn = document.getElementById("myBtn");		//也可以用其他方法获取
btn.onclick = function(){
    //事件处理程序
}
  • 使用DOM0级方法指定的事件被认为是元素的方法,因此这种事件处理程序是在元素的作用域上运行的,程序中的this引用当前元素
  • 以这种方法添加的事件处理程序在事件流的冒泡阶段被处理
  • 通过将事件处理程序属性的值设置为null,就可以删除事件处理程序

DOM2级事件处理程序

var A = document.getElementById("元素ID");		//也可以用其他方法获取

//使用匿名函数作为事件处理函数
A.addEventListener("事件名",function(){	//事件名不以on开头
    //事件处理程序
},布尔值);	//第三个参数为一个布尔值,true:在捕获阶段调用事件处理程序,false:在冒泡阶段调用事件处理程序

//使用具体函数对象作为事件处理函数
A.addEventListener("事件名",函数对象,布尔值);

//removeEventListener()的参数与addEventListener()完全相同,一字不差,但若事件处理函数为匿名函数,则无法移除(因为多个相同的匿名函数不是同一个函数对象)
A.removeEventListener("事件名",函数对象,布尔值);
  • 使用DOM2级方法指定的事件也被认为是元素的方法,在元素的作用域上运行,程序中的this引用当前元素
  • DOM2级方法的优点是可以多次调用addEventListener()方法添加多个事件处理函数,多个事件处理函数会按照它们被添加的顺序被触发
  • 大多数情况下,都将事件处理程序添加到事件流的冒泡阶段(既第三个参数设置为false),可以最大限度地兼容各种浏览器

IE事件处理程序

var A = document.getElementById("元素ID");		//也可以用其他方法获取

//使用匿名函数作为事件处理函数
A.attachEvent("on事件名",function(){
    //事件处理程序
});

//使用具体函数对象作为事件处理函数
A.attachEvent("on事件名",函数对象);

//detachEvent()的参数与attachEvent()完全相同,一字不差,但若事件处理函数为匿名函数,则无法移除(因为多个相同的匿名函数不是同一个函数对象)
A.detachEvent("on事件名",函数对象);

使用attachEvent()方法添加的事件处理函数作用域为全局作用域,this等于window

attachEvent()方法可以为元素添加多个事件处理函数,多个事件处理函数会按照它们被添加的相反顺序被触发(注意是相反顺序)

跨浏览器的事件处理程序

//使用EventUtil对象的addHandler()方法添加事件处理函数,removeHandler()方法移除事件处理函数
var EventUtil = {
    addHandler : function(element,type,handler){
        if(element.addEventListener){		//DOM2
            element.addEventListener(type,handler,false);
        } else if(element.attachEvent){		//IE
            element.attachEvent("on"+type,handler);
        } else{		//其他方法都无效时默认采用DOM0级方法
            element["on"+type] = handler;
        }
    },
    removeHandler : function(element,type,handler){		//参数与addHandler()完全相同
        if(element.removeEventListener){	//DOM2
            element.removeEventListener(type,handler,false);
        } else if(element.detachEvent){		//IE
            element.detachEvent("on"+type,handler);
        } else{		//其他方法都无效时默认采用DOM0级方法
            element["on"+type] = null;
        }
    }
};

var A = document.getElementById("元素ID");	//也可以用其他方法获取
var handler = function(){
    //事件处理程序
}
EventUtil.addHandler(A,"事件名",handler);	  //添加事件处理函数
EventUtil.removeHandler(A,"事件名",handler);	//移除事件处理函数

事件对象

  • 在触发DOM上的某个事件时,会产生一个事件对象event,这个对象包含着所有与事件有关的信息
  • 只有在事件处理程序执行期间,event对象才存在,一旦事件处理程序执行完毕,event对象会被销毁

DOM中的事件对象

兼容DOM的浏览器会将一个event对象传入事件处理程序中(无论DOM0还是DOM2)

event对象包含与创建它的特定事件有关的属性和方法,触发的事件类型不一样,可用的属性和方法也不一样

event共有属性

属性/方法 类型 说明
bubbles Boolean 表明事件是否冒泡
cancelable Boolean 表明是否可以取消事件的默认行为
currentTarget Element 事件处理程序当前正在处理的那个元素
defailtPrevented Boolean true:已调用preventDefault()
detail Integer 与事件相关的细节信息
eventPhase Integer 调用事件处理程序的阶段(1:捕获阶段,2:处于目标,3:冒泡阶段)
preventDefault() Function 取消事件的默认行为,cancelable为true时才可使用
stopImmediatePropagation() Function 取消事件的进一步捕获或冒泡,同时阻止任何事件处理程序被调用
stopPropagation() Function 取消事件的进一步捕获或冒泡,bubbles为true时才可使用
target Element 事件的目标
isTrusted Boolean true:事件是通过浏览器生成的,false:事件是通过JavaScript创建的
type String 被触发的事件的类型
view AbstractView 与事件关联的抽象视图,等同于发生事件的window对象

在事件处理程序内部:

  • this始终等于currentTarget
  • target只包含事件的实际目标
  • 如果直接将事件处理程序指定给了目标元素( A.οnclick=function(event){……} ),则this,currentTarget,target包含相同的值

如果事件处理程序存在于触发事件的元素的父元素中:

  • currentTarget = 父元素
  • this = 父元素
  • target = 触发事件的元素(子元素)

一个函数处理多个事件

在需要通过一个函数处理多个事件时,可以使用type属性:

//将该函数作为事件处理函数与多个事件绑定
var handler = function(event){
    switch(event.type){
        case "事件名1":
            事件处理程序1
            break;
        case "事件名2":
            事件处理程序2
            break;
        …………
    }
};

阻止特定事件的默认行为

  • 使用event.preventDefault()
  • 只有cancelable为true才能使用preventDefault()

停止事件传播

  • 使用event.stopPropagation()
  • stopPropagation()方法用于立即停止事件在DOM层次中的传播,既取消进一步的事件捕获或冒泡

IE中的事件对象

访问IE中的event对象的方法取决于指定事件处理程序的方法

  • 在使用DOM0方法添加事件处理程序时,event对象作为window对象的一个属性存在
  • 若事件处理函数是通过attachEvent()方法添加的,那么会有一个event对象作为参数传入事件处理函数
    • 在使用attachEvent()的情况下,也可以使用window.event来访问event对象

event共有属性

属性/方法 类型 说明
cancelBubble Boolean 默认false,将其设置为true即可取消事件冒泡(与DOM的stopPropagation()作用相同)
returnValue Boolean 默认true,将其设置为false即可取消事件默认行为(与DOM的preventDefault()作用相同)
srcElement Element 事件的目标(与DOM的target属性相同)
type String 被触发的事件的类型
  • 因为事件处理函数的作用域是根据指定它的方式来确定的,所以不能认为this始终等于事件目标,最好使用srcElement更保险

跨浏览器的事件对象

var EventUtil = {
    //以下为添加、移除事件处理函数的方法
    addHandler : function(element,type,handler){
        if(element.addEventListener){
            element.addEventListener(type,handler,false);
        } else if(element.attachEvent){
            element.attachEvent("on"+type,handler);
        } else{
            element["on"+type] = handler;
        }
    },
    removeHandler : function(element,type,handler){
        if(element.removeEventListener){
            element.removeEventListener(type,handler,false);
        } else if(element.detachEvent){
            element.detachEvent("on"+type,handler);
        } else{
            element["on"+type] = null;
        }
    }
    
    
    //以下为有关事件对象的操作
    getEvent : function(event){			//获取事件对象
        return event ? event : window.event;
    },
    getTarget : function(event){		//获取事件的目标
        return event.target || event.srcElement;
    },
    preventDefault : function(event){	//取消事件默认行为
        if(event.preventDefault){
            event.preventDefault();
        } else{
            event.returnValue = false;
        }
    },
    stopPropagation : function(event){	//取消事件捕获或冒泡
        if(event.stopPropagation){
            event.stopPropagation();
        } else{
            event.cancelBubble = true;
        }
    }
};


//使用方法
var A = document.getElementById("元素ID");
A.onclick = function(event){
    event = EventUtil.getEvent(event);			//获取事件对象
    var target = EventUtil.getTarget(event);	 //获取事件的目标
    EventUtil.preventDefault(event);		    //取消事件默认行为
    EventUtil.stopPropagation(event);			//取消事件捕获或冒泡
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JavaScript常用事件讲解 的相关文章

  • 将 next.js 与纱线工作区结合使用

    今天遇到了这样的项目结构的复杂情况 packages app pages package json ui kit pages package json shared babelrc package json root lvl 包 json
  • Kendo UI 网格过滤器日期格式

    在我的剑道网格中 我想更改过滤器中的日期格式 例如 2015年1月30日至2015年1月30日 我已经更改了开始日期的日期格式 field StartDate title Start Date width 30 format 0 MMM d
  • Jquery文件上传插件进度条

    这个插件 https github com blueimp jQuery File Upload wiki管理网页中的文件上传 并且可以在上传过程中添加很多 UI 元素 您创建一个输入文件类型元素 然后绑定 js 文件 使用实例化代码和 w
  • JS 在两个或多个点之间画线

    我需要在两个标签或标签之间画一条线 Example http caitriona github io connect the dots http caitriona github io connect the dots 我需要做这样的事情
  • mocha.opts 已弃用,如何迁移到 package.json?

    我正在开发一个大型项目 自从上周我更新了摩卡以来 现在我们收到警告 DeprecationWarning 通过 mocha opts 进行的配置已被弃用并且 将从 Mocha 的未来版本中删除 使用 RC 文件或 改为 package js
  • 弃用警告:时刻构造回退到 js Date

    我正在尝试转换这个日期时间 150423160509 这是 utc 日期时间 改为以下格式 2015 04 24 00 05 09 本地时区 通过使用 moment js var moment require moment timezone
  • Cordova SQLite 保存 BLOB

    我的 Cordova SQLite 插件有问题 如何将 BLOB 图像保存到 SQLite 我在 JS 中有 BLOB 对象 Blob size 96874 type image jpeg proto Blob length 1 我试图拯救
  • jQuery数据表设置列设计和成功回调中的值

    我为我的数据表编写了以下代码 它用我的数据库中的内容填充表 如下所示 if datatable null datatable destroy datatable tableProducts DataTable pageLength 50 b
  • Javascript 制作音频 blob

    我正在测试 html 音频标签 我想制作音频 blob url 就像 youtube 或 vimeo 那样 并将其添加到 src 开始播放音频 我一直在测试new Blob and URL createObjectURL 但我不知道如何使用
  • 光标:IE 8 和 9 中的自动行为

    我想要的是为整个正文标记指定cursor pointer 这样页面的背景是可点击的 但我也希望页面的其余部分像以前一样工作 所以我尝试为div设置cursor auto 其中包含这一页 在 FF Chrome 和 safari 中 它工作得
  • 如何将查询参数添加到守卫中的路由并将其传递给 Angular 4 中的组件?

    我在我的 Angular 4 应用程序中使用路由保护 如果条件满足并返回 true 我想向路由添加一个查询参数 这是我一直在研究的代码 Injectable export class ViewGuardService implements
  • 如何显示/隐藏jsf组件

    在我的一个 JSF 应用程序中 顶部的标题部分包含 selectOneMenu 底部的内容部分显示过滤器组件 默认情况下 应用程序首先在顶部显示 selectOneMenu 数据 在底部显示相应的 Filter 信息 如果用户选择不同的se
  • 预加载 javascript 和 css 文件

    我目前正在开发一个移动网站 该网站大量使用图像 CSS 和 JavaScript 例如 它使用未压缩的 150KB 的库 我为图像构建了一个预加载器 效果相当好 function loadImages images var sum 0 fo
  • dc lineChart 单击时弹出数据点信息

    我正在尝试检测折线图数据点上的点击 Per this answer dc scatter plot binding onClick event https stackoverflow com a 22772340 1873386 I am
  • Google 地图 Javascript v3 折线点击事件

    我正在尝试显示一张地图 其中有多条路线布置为折线 单击多段线时 我想显示特定于该线的数据 将数据与线关联不是问题 但无论单击哪条线 显示的数据都会与最近绘制的线关联 就好像每条新折线都会覆盖最后一条线一样 我有一个数据库 其中包含 gpx
  • Jquery 子元素发生变化

    我正在尝试使用 jquery 在子元素 在本例中为 select 更改时触发事件 这是我的 HTML div class row addForm div class col lg 2 col md 2 col sm 3 col xs 6 d
  • 如何使用 Node.js 解析 JSON? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我应该如何使用 Node js 解析 JSON 是否有一些模块可以安全地验证和解析 JSON 你可以简单地使用JSON parse h
  • 如何使用转义的 unicode 解码字符串?

    我不确定这叫什么 所以我在搜索时遇到了麻烦 如何使用 unicode 解码字符串http u00253A u00252F u00252Fexample com to http example com使用 JavaScript 我试过unes
  • 如何使用 API 中的数据填充选择的下拉元素 - ReactJS

    我对 React 还很陌生 我正在从 API 获取数据 当我检查控制台日志时可以看到数据 但是我不知道如何使用 map 创建一个新数组 然后选项元素可以使用该数组来显示货币代码 目前它填充下拉列表 但选项元素全部为空 结果显示为 NaN 下
  • redux - 如何存储和更新键/值对

    我正在使用 redux 和 React js 我想存储简单的键 值对 但无法获得正确的减速器语法 在这种情况下 每个键 值对将保持与外部系统的连接 这是正确的做法吗 我刚开始使用 redux 所以这有点神秘 export default s

随机推荐

  • 华为手机信息不弹屏了为什么_华为手机短信不提醒怎么办?华为手机短信提醒设置方法...

    华为手机短信提醒设置方法 1 检查当前设置的默认短信应用是哪个应用 点击桌面 设置 图标 找到 应用程序管理 选择 默认应用设置 选择 信息 可以看到当前正在使用的默认短信应用名称 如果使用的是第三方短信应用 请将 信息 勾选 改为使用默认
  • STM32 ADC转换+DMA传输(详解)

    1 选题背景 最近刚入坑 看了半个多月的入门视频并动手了一些简单的实验 但看工程项目的代码总是很费劲 便想以一个有难度的课题来进一步入门嵌入式开发 这个选题充分使用了STM32的各种片上外设 包括定时器 ADC模 数变换 GPIO口和DMA
  • [算法] 弗洛伊德算法 找出所有顶点之间最短距离

    package com guigu algorithm floydAlgorithm import java util Arrays author guorui fu versiion 1 0 弗洛伊德算法 本质就是将邻接矩阵中N值填满 时
  • 邮件程序 php_PHP

    PHP 发送电子邮件 PHP 允许您从脚本直接发送电子邮件 PHP mail 函数 PHP mail 函数用于从脚本中发送电子邮件 语法 mail to subject message headers parameters 参数 描述 to
  • Buffer Cache和Page Cache

    概念 如高速缓存 cache 产生的原理类似 在I O过程中 读取磁盘的速度相对内存读取速度要慢的多 因此为了能够加快处理数据的速度 需要将读取过的数据缓存在内存里 而这些缓存在内存里的数据就是高速缓冲区 buffer cache 下面简称
  • element tab-pane切换标签页 自动刷新

    解决方法 在子组件上加 v if
  • Kali如何配置静态IP,并且实现网络访问

    1 本地网络配置 我是使用VMware workstation的桥接网络 配置IP要根据对应的网络模式下对应的网络段进行配置 才能保证Kali与别的主机正常通信 桥接网络模式 我需要先看一下宿主机的网络IP地址 WIN r输入cmd 回车
  • 2013/1工作总结

    这个月抽时间看了C Primer一书 主要原因是没有基础知识直接看ATL的代码根本不可能 感想之一就是程序员也许必须学习一下C 只学习Java或者C 可能对语言的了解有限 造成对某些问题一直没有透彻的理解 当然了 最后发现还要好好学习理解编
  • TCP思维导图

  • GTest源码剖析(四)——TEST_P宏

    GTest源码剖析 TEST P宏 GTest源码剖析TEST P宏 TEST P宏用法 TestWithParam 类 1 TestWithParam 类定义 2 WithParamInterface 模版类定义 INSTANTIATE
  • 使用CURL上传图片至远程服务器(PHP >5.5)

    开头引入 use CURLFile curl文件上传 接收并上传 if FILES data file new CURLFile FILES file1 tmp name image jpeg FILES file1 name 文件流 fi
  • MVP和MVC的区别

    前提回顾 MVC架构 MVC就是Model View Controller 它们的作用是 它们之间的关系如下图所示 View传送指令到Controller Controller完成业务逻辑后 改变Model的状态 Model将新的数据发送到
  • RPC 开发系列一:RPC 基本介绍

    一 什么是 RPC RPC 的全称是 Remote Procedure Call 即远程过程调用 功能 屏蔽远程调用跟本地调用的区别 让我们感觉就是调用项目内的方法 隐藏底层网络通信的复杂性 让我们更专注于业务逻辑 二 RPC 通信流程 发
  • sourceforge文件下载过慢之原始解决方法

    近日 从sourceforge下载文件超线慢 从下午一直下载到网上11点多 居然下不完39MB的资料 百度一下方法有很多 却一个都没成功 比如 http sourceforge mirrorservice org 更是没用 部份有用 因为不
  • __cdecl __stdcall __fastcall区别

    一 三者区别一览表 stdcall cdecl fastcall 参数传递方式 右 gt 左 压栈 右 gt 左 压栈 左边开始的两个不大于4字节 DWORD 的参数分别放在ECX和EDX寄存器 其余的参数仍旧自右向左压栈传送 清理栈方 被
  • 【逆波兰表达式求值】

    逆波兰表达式求值 给你一个字符串数组 tokens 表示一个根据 逆波兰表示法 表示的算术表达式 请你计算该表达式 返回一个表示表达式值的整数 注意 有效的算符为 和 每个操作数 运算对象 都可以是一个整数或者另一个表达式 两个整数之间的除
  • 【SpringBoot框架篇】31.基于分布式锁或xxx-job实现分布式任务调度

    文章目录 1 简介 2 分布式锁实现 2 1 引用依赖 2 2 定义分布式锁注解 2 3 配置切入点和获取锁释放锁逻辑 2 4 测试任务 3 使用分布式任务调度平台xxx job 3 1 下载源码并运行项目 3 2 springBoot项目
  • 微信小程序之授权登录篇

    之前微信授权登录时是直接可以通过getUserInfo接口 弹出授权弹窗 由于微信官方修改了 getUserInfo 接口 所以现在无法实现一进入微信小程序就弹出授权窗口 只能通过 button 去触发 微信的官方解释如下 为优化用户体验
  • React 初识之Umi项目搭建实战

    一 创建项目 创建之前需要安装 Node js 和 npm yarn 这俩个环境 在WebStorm里面创建一个项目 输入命令 yarn create umi 弹出选项 这里我们选择第二项APP 选择是否使用typescript 这里选no
  • JavaScript常用事件讲解

    声明 本人的所有博客皆为个人笔记 作为个人知识索引使用 因此在叙述上存在逻辑不通顺 跨度大等问题 希望理解 分享出来仅供大家学习翻阅 若有错误希望指出 感谢 事件流 事件流描述的是从页面接收事件的顺序 事件冒泡 事件开始由最具体的元素接收