2022-07-13 JavaScript基础学习 - 事件

事件

事件是 JavaScript 与 HTML 的交互的实现。
事件冒泡流又称作 IE 事件流,被定义为从最具体的元素传播到不那么具体的元素,触发顺序也就是由深到表;事件捕获流,被定义为从最不具体的元素到最具体的元素,触发顺序也就是由表到深。
DOM0级事件:获取元素后,使用元素的事件属性绑定方法
const div = document.getElementById("div");
div.onclick = function() {
console.log(this.id);
}
在该段代码中,this 指的是元素本身(此处引申出一个 this 相关的指向问题)。如果需要移除对应事件程序,则将其对应的事件复制为 null
DOM2级事件:使用 addEventListener 和 removeEventListener (事件[不带on];触发函数;true[事件捕获] / false[默认,事件冒泡])
const div = document.getElementById("div");
div.addEventListener("click", function(){
console.log(this.id)
}, false);
注意 removeEventListener 无法删除匿名函数
IE版:attachEvent 和 detachEvent (事件[如 onclick];触发函数)
const div = document.getElementById("div");
div.attachEvent("onclick", function(){
console.log(this === window); // true
})
IE版的事件绑定作用域在全局中生效运行,所以this 等于window ;IE版事件绑定多次函数时,会从最后一个绑定的函数开始触发(逆序)
删除同 removeEventListener

跨浏览器事件处理程序

const EvnetUtil = {
// 绑定
addHandler: function(eve, type, callback){
if (eve.addEventListener) {
eve.addEventListener(type, callback);
} else if (eve.attachEvent) {
eve.attachEvent(on${type}, callback);
} else {
eve[on${type}] = callback;
}
},
// 删除
removeHandler: function(eve, type, callback){
if (eve.removeEventListener) {
eve.removeEventListener(type, callback);
} else if (eve.detachEvent) {
eve.detachEvent(on${type}, callback);
} else {
eve[on${type}] = null;
}
},
}

新写法

const btn = document.getElementById("myBtn");
const handler = function (event) {
switch(event.type){
case "click":
console.log("clicked");
break;
case "mouseover":
event.target.style.backgroundColor = "red";
break;
case "mouseout":
event.target.style.backgroundColor = "";
break;
}
}
btn.onclick = handler;
btn.onmouseover = handler;
btn.onmouseout = handler;

--

preventDefault() 阻止特定事件的默认动作,如链接跳转
stopPropagetion() 立即阻止事件流在DOM结构中的传播(比如按钮和body同时设置点击,但是按钮触发后不会继续冒泡到body)

IE事件对象

如果事件处理程序是使用 DOM0 方式指定的,则event 对象只是window 对象的一个属性
const btn = document.getElementById("myBtn");
btn.onclick = function () {
let event = window.event;
console.log(event.type); // click
}
如果事件处理程序是使用 DOM2 方式指定的(attachEvent ),则event 会作为唯一参数传给处理函数;
const btn = document.getElementById("myBtn");
btn.attachEvent("onclick", function(event){
console.log(event.type); // click
})
IE事件阻止默认行为;
const link = document.getElementById("myLink");
link.onclick = function(){
window.event.returnValue = false; // 取 false
}
IE事件阻止事件流传播;
const btn = document.getElementById("myBtn");
btn.onclick = function(){
window.event.cancelBubble = true; // 取 true
}

事件类型

用户界面事件(UIEvent):涉及与BOM交互的通用浏览器事件;
焦点事件(FocusEvent):在元素获得和失去焦点时触发;
鼠标事件(MouseEvent):使用鼠标在页面上执行某些操作时触发;
滚轮事件(WheelEvent):使用鼠标滚轮或类似设备时触发;
输入事件(InputEvent):向文档中输入文本时触发;
键盘事件(KeyboardEvent):使用键盘在页面上执行某些操作时触发;
合成事件(CompositionEvent):在使用某种 IME 输入字符时触发;

用户页面事件

‒ load:在 window 上当页面加载完成后触发 / 方式1:DOM0 或 DOM2 在 window 上绑定 / 方式2:向<body> 元素添加 onload 属性;
‒ unload:会在文档卸载完后触发,常用在从一个页面导航到另一个页面时触发,清理旧页面引用 / 方式1:DOM0 或 DOM2 在 window 上绑定 / 方式2:向<body> 元素上添加 onunload 属性;
‒ resize:当浏览器窗口被缩放到新的高宽度时触发,浏览器的最大化和最小化也会触发事件;
‒ scroll:当用户滚动包含滚动条的元素时触发;
‒ select:在文本框上当用户选择了一个或多个字符时触发;
‒ error:在 window 上当 JavaScript 报错时触发;
‒ abort

焦点事件

‒ blur:当元素失去焦点时触发,不冒泡;
‒ focus:当元素获取焦点时触发,不冒泡;
‒ focusin:同focus,冒泡版;
‒ focusout:同blur,冒泡版;

鼠标和滚轮事件

‒ click:在用户单击鼠标左键或按键盘回车键时触发;
‒ dbclick:在用户双击鼠标左键时触发;
‒ mousedown:在用户按下任意鼠标键时触发,不联动键盘;
‒ mouseenter:在用户把鼠标光标从元素外部移动到内部时触发,不冒泡,不会在后代元素上触发;
‒ mouseleave:在用户把鼠标光标从元素内部移动到外部时触发,不冒泡,不会在后代上触发;
‒ mousemove:鼠标在元素上移动时触发;
‒ mouseout:在鼠标从元素移动到另一个元素时触发,另一个元素可以是父级也可以是子级;
‒ mouseover:在用户把鼠标光标从元素外部移入内部时触发;
‒ mouseup:当用户释放鼠标键时触发;
‒ 客户端坐标:通过event 对象的clientX 和clientY 属性获取,基于浏览器视口;
‒ 页面坐标:通过event 对象的pageX 和pageY 属性获取,基于页面内容;
‒ 屏幕坐标:通过event 对象的screenX 和screeY 属性获取,基于屏幕;
‒ 修饰键:shiftKey、ctrlKey、altKey、metaKey

键盘与输入事件

‒ keydown:用户按下某个键时触发,持续按住持续触发;
‒ keyup:用户释放按键时触发;
‒ 使用keyCode 获取键码;
‒ textInput:只能在可编辑区域上,字符被输入时触发,使用 event.data 可以调出要插入的字符的内容

HTML事件

‒ contextmenu
‒ beforunload:页面即将从浏览器中卸载时触发;
‒ DOMContentLoaded:DOM树构建完成后立即触发;
‒ readystatechange:意在提供文档或元素加载状态的信息(原以为是Ajax里专属的,实际不是);
‒ pageshow、pagehide:pageshow在load之后触发,pagehide在unload之前触发;

设备事件

‒ orientationcahgne:判断手机属于垂直还是水平模式,window.orientation 属性可以获取
‒ deviceorientation:判断手机在XYZ轴上的旋转;
‒ devicemotion:判断设备在移动

触摸及手势事件

‒ touchstart:手指放在触摸屏上时触发
‒ touchmove:手指在触摸屏上滚动时触发,可以使用preventDefault() 阻止
‒ touchend:手指离开时触发;
‒ touchcancel:系统停止跟踪触摸时触发;


‒ gesturestart:一个手指已经在屏幕上,另一个手指放到屏幕上时触发;
‒ gesturechange:任何一个手指在屏幕上的位置发生变化时触发;
‒ gestureend:其中一个手指离开屏幕时触发;

性能与内存

  1. 事件委托:事件委托利用事件冒泡的机制,可以只使用一个事件处理程序来管理一种类型的事件
  2. 删除事件处理程序:使用 innerHTML 替换内容时,绑定在组件上的方法程序并没有跟着被清除

模拟事件

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 195,719评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,337评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 142,887评论 0 324
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,488评论 1 266
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,313评论 4 357
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,284评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,672评论 3 386
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,346评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,644评论 1 293
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,700评论 2 312
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,457评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,316评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,706评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,990评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,261评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,648评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,859评论 2 335

推荐阅读更多精彩内容