js 事件模型 + ( 事件类型 )
Dom事件
事件是一种异步编程的实现方式,本质上是程序各个组成部分之间的通信。DOM支持大量的事件
(一) EventTarget接口
DOM的事件操作(监听和触发),都定义在EventTarget接口。Element节点、document节点和window对象,都部署了这个接口。
EventTarget接口有三个方法:
- addEventListener:绑定事件的监听函数
- removeEventListener:移除事件的监听函数
- dispatchEvent:触发事件
(1) addEventListener() 方法
addEventListener方法用于在当前节点或对象上,定义一个特定事件的监听函数。
target.addEventListener(type, listener, options);
- addEventListener方法接受三个参数。
type:事件名称,大小写敏感。
listener:监听函数。事件发生时,会调用该监听函数。
useCapture:布尔值,表示监听函数是否在捕获阶段(capture)触发,默认为false(监听函数只在冒泡阶段被触发)。老式浏览器规定该参数必写,较新版本的浏览器允许该参数可选。为了保持兼容,建议总是写上该参数。 - addEventListener方法可以为当前对象的同一个事件,添加多个监听函数。这些函数按照添加顺序触发,即先添加先触发。如果为同一个事件多次添加同一个监听函数,该函数只会执行一次,多余的添加将自动被去除(不必使用removeEventListener方法手动去除)。
- addEventListener方法指定的监听函数,内部的this对象总是指向触发事件的那个节点。
window.onload = function() {
var a = document.getElementById('a');
var go = function() {
console.log('这是addEventListener函数')
}
var to = function() {
console.log('addEventListener可以为当前对象的同一事件,绑定不同的监听函数,先绑定的先执行')
}
a.addEventListener('click', go, false) // 为a的 click事件 绑定了 监听函数go,在冒泡阶段触发
a.addEventListener('click', to, false) // 为当前对象 同一事件 绑定不同的 监听函数
}
--------------------------------------------------------------------------------
function hello() {
console.log('Hello world');
}
document.addEventListener('click', hello, false);
document.addEventListener('click', hello, false);
// 执行上面代码,点击文档只会输出一行Hello world
- 如果希望向监听函数传递参数,可以用匿名函数包装一下监听函数。
function print(x) {
console.log(x);
}
var el = document.getElementById('div1');
el.addEventListener('click', function () { print('Hello'); }, false);
---------------------------------------------
window.onload = function () {
var a = document.getElementById('a');
var go = function(x,e) {
console.log(x)
console.log(e,'每一个事件都会生成一个事件对象,作为参数,传给监听函数') //比如e.target等
};
a.addEventListener('click', function(e){ go('wang',e) }, false)
var b = new Event('click');
var c = a.dispatchEvent(b);
console.log(c,'dispatchEvent()方法返回布尔值')
};
(2) removeEventListener() 方法
removeEventListener方法用来移除addEventListener方法添加的事件监听函数。
-
参数: 与 addEventListener()方法一致 有三个参数,分别是:
1.事件名称,
.2监听函数,
3.布尔值是否在捕获阶段触发,默认是false -
注意:
removeEventListener方法移除的监听函数,必须与对应的addEventListener方法的参数完全一致,而且必须在同一个元素节点,否则无效。
(3) dispatchEvent() 方法-------------触发事件
dispatchEvent方法在当前节点上触发指定事件,从而触发监听函数的执行。该方法返回一个布尔值,只要有一个监听函数调用了Event.preventDefault(),则返回值为false,否则为true。
-
dispatchEvent方法的参数是一个Event对象的实例。
-
如果dispatchEvent方法的参数为空,或者不是一个有效的事件对象,将报错。
-
dispatchEvent() 在当前节点上触发指定事件------从而触发事件上绑定的监听函数去执行
-
dispatchEvent() 方法返回一个布尔值,只要有一个监听函数调用了 Event.preventDefault(),就会返回false,否则返回true-------( 同一个事件,可以绑定多个监听函数 )`
para.addEventListener('click', hello, false);
var event = new Event('click');
para.dispatchEvent(event);
// 上面代码在当前节点触发了click事件。
----------------------------------------------------
var c = document.getElementById('c');
function dispatch() {
console.log(
'dispatchEvent()作用是触发事件,参数是Event对象的实例,触发事件,从而出发事件绑定的监听函数'
)
}
c.addEventListener('click', dispatch, false);
var click = new Event('click');
var d = c.dispatchEvent(click); // dispatchEvent()事件执行后,返回一个布尔值
console.log(d) // true
// ------(只要有一个监听函数调用了 Event.preventDefault(),就会返回false,否则返回true)
(二) 监听函数
监听函数(listener)是事件发生时,程序所要执行的函数。
- DOM提供三种方法,可以用来为事件绑定监听函数。
(1) HTML标签的on-属性
HTML语言允许在元素标签的属性中,直接定义某些事件的监听代码。
- 使用这个方法指定的监听函数,只会在冒泡阶段触发。
“HTML标签的on-属性”,违反了HTML与JavaScript代码相分离的原则;
<body onload="doSomething()">
<div onclick="console.log('触发事件')">
// 上面代码为body节点的load事件、div节点的click事件,指定了监听函数。
// 使用这个方法指定的监听函数,只会在冒泡阶段触发。
- 注意,使用这种方法时,on-属性的值是将会执行的代码,而不是一个函数。
<!-- 正确 -->
<body onload="doSomething()">
// on-属性 方法,标签中 属性的值 是将要执行的代码,而不是函数(即 执行函数,而不是定义函数 )
<!-- 错误 -->
<body onload="doSomething">
- Element元素节点的setAttribute方法,其实设置的也是这种效果。
el.setAttribute('onclick', 'doSomething()');
等同于
<body onclick="doSomething()"> // 这里的c,大小写都可以
(2) Element节点的事件属性
Element节点对象有事件属性,同样可以指定监听函数。
- 使用这个方法指定的监听函数,只会在冒泡阶段触发。
“Element节点的事件属性”的缺点是,同一个事件只能定义一个监听函数,也就是说,如果定义两次onclick属性,后一次定义会覆盖前一次。
window.onload = doSomething;
div.onclick = function(event){
console.log('触发事件');
};
// 使用这个方法指定的监听函数,只会在冒泡阶段触发。
(3) addEventListener方法
-
在上面三种方法中:
-
第一种“HTML标签的on-属性”,违反了HTML与JavaScript代码相分离的原则;
-
第二种“Element节点的事件属性”的缺点是,同一个事件只能定义一个监听函数,也就是说,如果定义两次onclick属性,后一次定义会覆盖前一次。
-
因此,这两种方法都不推荐使用,除非是为了程序的兼容问题,因为所有浏览器都支持这两种方法。
-
addEventListener是推荐的指定监听函数的方法。有如下三个优点:
-
1.可以针对同一个事件,添加多个监听函数。
-
2.能够指定在哪个阶段(捕获阶段还是冒泡阶段)触发回监听函数。
-
3.除了DOM节点,还可以部署在window、XMLHttpRequest等对象上面,等于统一了整个JavaScript的监听函数接口。
(4) 在监听函数中 this的指向
实际编程中,监听函数内部的this对象,常常需要指向触发事件的那个Element节点。
- addEventListener方法指定的监听函数,内部的this对象总是指向触发事件的那个节点。
- 如果将监听函数部署在Element节点的on-属性上面,this不会指向触发事件的元素节点。
// HTML代码为
// <p id="para">Hello</p>
var id = 'doc';
var para = document.getElementById('para');
function hello(){
console.log(this.id); // addEventListener监听函数中的this,总是指向 触发事件的那个节点
}
para.addEventListener('click', hello, false);
总结
- 总结一下,以下写法的this对象都指向Element节点。
// JavaScript代码
element.onclick = print
element.addEventListener('click', print, false)
element.onclick = function () {console.log(this.id);}
// HTML代码
<element onclick="console.log(this.id)">
--------------------------------------------------------
- 以下写法的this对象,都指向全局对象。
// JavaScript代码
element.onclick = function (){ doSomething() };
element.setAttribute('onclick', 'doSomething()');
// HTML代码
<element onclick="doSomething()">
(三) 事件的传播
当一个事件发生以后,它会在不同的DOM节点之间传播(propagation)。这种传播分成三个阶段:
-
第一阶段:从window对象传导到目标节点,称为“捕获阶段”(capture phase)。
-
第二阶段:在目标节点上触发,称为“目标阶段”(target phase)。
-
第三阶段:从目标节点传导回window对象,称为“冒泡阶段”(bubbling phase)。
这种三阶段的传播模型,会使得一个事件在多个节点上触发。比如,假设点击<div>之中嵌套一个<p>节点。( phase是阶段的意思 )---------( bubbling是冒泡的意思 )
- 用户点击网页的时候,浏览器总是假定click事件的目标节点,就是点击位置的嵌套最深的那个节点(嵌套在<div>节点的<p>节点)。所以,<p>节点的捕获阶段和冒泡阶段,都会显示为target阶段。
- 事件传播的最上层对象是window,接着依次是document,html(document.documentElement)和body(document.body)。
-
也就是说,如果<body>元素中有一个<div>元素,点击该元素。事件的传播顺序:
(1) 在捕获阶段依次为window、document、html、body、div。
(2) 在冒泡阶段依次为div、body、html、document、window。
(四) 事件的代理
由于事件会在 冒泡阶段 向上传播到父节点,因此可以把子节点的监听函数定义在父节点上,由父节点的监听函数统一处理多个子元素的事件。这种方法叫做事件的代理(delegation)。
- 这样做的好处是,只要定义一个监听函数,就能处理多个子节点的事件,而且以后再添加子节点,监听函数依然有效。
var ul = document.querySelector('ul');
ul.addEventListener('click', function(event) {
if (event.target.tagName.toLowerCase() === 'li') {
// some code
}
});
---------------------------------------
实例:
--
html部分:
<div id="bubb" style="padding:20px;background:yellow; ">
<p style="background:blueviolet">这是div中的p元素</p>
<button style="background:royalblue">这是div中的按钮</button>
</div>
--
js部分:
var e = document.getElementById('bubb');
var func = function (event) {
var tagname = event.target.tagName.toLowerCase(); // 目标节点的标签名
if( tagname === 'p') {
console.log('这是p元素')
} else if( tagname === 'button') {
console.log('这是button')
} else {
console.log('这是div父元素')
}
};
e.addEventListener('click', func)
stopPropagation方法
- 如果希望事件到某个节点为止,不再传播,可以使用事件对象stopPropagation方法。
p.addEventListener('click', function(event) {
event.stopPropagation(); // stopPropagation() 阻止冒泡
});
// 用上面的代码以后,click事件在冒泡阶段到达<p>节点以后,就不再向上(父节点的方向)传播了。
stopImmediatePropagation方法
- 但是,stopPropagation方法只会阻止当前监听函数的传播,不会阻止<p>节点上的其他click事件的监听函数。如果想要不再触发那些监听函数,可以使用stopImmediatePropagation方法。
p.addEventListener('click', function(event) {
event.stopImmediatePropagation();
});
p.addEventListener('click', function(event) {
// 不会被触发
});
(5) Event对象
事件发生以后,会生成一个事件对象,作为参数传给监听函数。浏览器原生提供一个Event对象,所有的事件都是这个对象的实例,或者说继承了Event.prototype对象。
- 事件发生后,会生成一个事件对象,作为传给监听函数的参数
- 所有事件都是Event对象的实例,即 ( 所有事件都继承了Event.prototype对象 )
- Event对象本身就是一个构造函数,可以用来生成新的实例。
(1) Event构造函数接受两个参数:
-
第一个参数是字符串,表示事件的名称;
-
第二个参数是一个对象,表示事件对象的配置。该参数可以有以下两个属性。
bubbles:布尔值,可选,默认为false,表示事件对象是否冒泡。
cancelable:布尔值,可选,默认为false,表示事件是否可以被取消。
event = new Event(typeArg, eventInit);
var ev = new Event(
'look',
{
'bubbles': true,
'cancelable': false
}
);
document.dispatchEvent(ev);
// 上面代码新建一个look事件实例,然后使用dispatchEvent方法触发该事件。
例二:
para.addEventListener('click', hello, false);
var event = new Event('click');
para.dispatchEvent(event); // 触发事件
例三:
window.onload = function () {
var a = document.getElementById('a');
var go = function(x,e) {
console.log(x)
console.log(e,'每一个事件都会生成一个事件对象,作为参数,传给监听函数,')
console.log(e.bubbles,'e.bubbles') // 在监听函数中,获取是否冒泡,只读
};
a.addEventListener('click', function(e){ go('wang',e) }, false)
var b = new Event('click',{bubbles: true}); // 在创建click方法实例的时候,定义是否冒泡
var c = a.dispatchEvent(b);
console.log(c,'dispatchEvent()方法返回布尔值')
};
(2) event.bubbles
bubbles属性返回一个布尔值,表示当前事件是否会冒泡。该属性为只读属性,只能在新建事件时改变。除非显式声明,Event构造函数生成的事件,默认是不冒泡的。
- bubbles是冒泡的意思 (bubbling)
- event.bubsles 返回布尔值,表示当前事件是否会冒泡,默认是false
- event.bubbles 是只读属性
(3) event.eventPhase
eventPhase属性返回一个整数值,表示事件目前所处的阶段。
- phase 是阶段的意思
0,事件目前没有发生。
1,事件目前处于捕获阶段,即处于从祖先节点向目标节点的传播过程中。该过程是从Window对象到Document节点,再到HTMLHtmlElement节点,直到目标节点的父节点为止。
2,事件处目标阶段,事件到达目标节点,即target属性指向的那个节点。
3,事件处于冒泡阶段,即处于从目标节点向祖先节点的反向传播过程中。该过程是从父节点一直到Window对象。只有bubbles属性为true时,这个阶段才可能发生。--------3阶段,即冒泡阶段只有bubbles为true才有可能会发生
(4) event.cancelable
cancelable属性返回一个布尔值,表示事件是否可以取消。该属性为只读属性,只能在新建事件时改变。除非显式声明,Event构造函数生成的事件,默认是不可以取消的。
- 如果要取消某个事件,需要在这个事件上面调用preventDefault方法,这会阻止浏览器对某种事件部署的默认行为。
(5) defaultPrevented
defaultPrevented属性返回一个布尔值,表示该事件是否调用过preventDefault方法。
(6) currentTarget
currentTarget属性返回事件当前所在的节点,即正在执行的监听函数所绑定的那个节点。
作为比较,target属性返回事件发生的节点。如果监听函数在捕获阶段和冒泡阶段触发,那么这两个属性返回的值是不一样的。
- currentTarget 返回的是正在执行的监听函数所绑定的那个节点。
(7) target
target属性返回触发事件的那个节点,即事件最初发生的节点。如果监听函数不在该节点触发,那么它与currentTarget属性返回的值是不一样的。
-
target 返回触发事件的那个节点
事件代理中的 currentTarget 和 target
(8) event.type
type属性返回一个字符串,表示事件类型,大小写敏感。
- event.type 返回的是字符串,表示事件类型:比如click事件,mouseover事件等
- 大小写敏感
(9) event.detail
detail属性返回一个数值,表示事件的某种信息。具体含义与事件类型有关,对于鼠标事件,表示鼠标按键在某个位置按下的次数,比如对于dblclick事件,detail属性的值总是2。
- 返回一个数值
(10) event.timeStamp
timeStamp属性返回一个毫秒时间戳,表示事件发生的时间。
(11) isTrusted
isTrusted属性返回一个布尔值,表示该事件是否为真实用户触发。
- 用户触发的事件返回true,脚本触发的事件返回false。
(12) event.preventDefault()
preventDefault方法取消浏览器对当前事件的默认行为
- event.preventDefault方法生效的前提是:事件对象的cancelable属性为true,如果为false,则调用该方法没有任何效果。
- 该方法不会阻止事件的进一步传播(stopPropagation方法可用于这个目的)。只要在事件的传播过程中(捕获阶段、目标阶段、冒泡阶段皆可),使用了preventDefault方法,该事件的默认方法就不会执行。
(13) event.stopPropagation()
stopPropagation方法阻止事件在 DOM 中继续传播,防止再触发定义在别的节点上的监听函数,但是不包括在当前节点上新定义的事件监听函数。
事件类型
(一) 鼠标事件
(1) click事件
当用户在Element节点、document节点、window对象上单击鼠标(或者按下回车键)时,click事件触发。
- “鼠标单击”定义为,用户在同一个位置完成一次mousedown动作和mouseup动作。它们的触发顺序是:mousedown首先触发,mouseup接着触发,click最后触发。
(2) dblclick事件
dblclick事件当用户在element、document、window对象上,双击鼠标时触发。该事件会在mousedown、mouseup、click之后触发。
(3) mousedown事件
mousedown在按下鼠标键时触发。
(4) mouseup 事件
mouseup在释放按下的鼠标键时触发。
(5) mousemove事件
mousemove事件当鼠标在一个节点内部移动时触发。当鼠标持续移动时,该事件会连续触发。为了避免性能问题,建议对该事件的监听函数做一些限定,比如限定一段时间内只能运行一次代码。
- mousemove事件在节点内部移动时触发。
- 当鼠标持续移动时,会连续触发
- 性能优化,对监听函数做限制,如:一定时间内只能运行一次代码
(6) mouseover事件 和 mouseenter事件
mouseover事件和mouseenter事件,都是鼠标进入一个节点时触发。
- 两者的区别是:
- mouseenter事件只触发一次,
- 而只要鼠标在节点内部移动,mouseover事件会在 (子节点) 上触发多次。!!! ( 重要 )
(7) mouseout 事件,mouseleave 事件
mouseout事件和mouseleave事件,都是鼠标离开一个节点时触发。
- 两者的区别是:
- mouseout事件会冒泡,mouseleave事件不会。
- 子节点的mouseout事件会冒泡到父节点,进而触发父节点的mouseout事件。
- mouseleave事件就没有这种效果,所以离开子节点时,不会触发父节点的监听函数。
(8) contextmenu 事件
contextmenu事件在一个节点上点击鼠标右键时触发,或者按下“上下文菜单”键时触发。
(二) 滚轮事件
(1) wheel事件
wheel事件是与鼠标滚轮相关的事件,目前只有一个wheel事件。用户滚动鼠标的滚轮,就触发这个事件。
- wheel是滚轮的意思
- wheel事件除了继承了MouseEvent、UIEvent、Event 的属性,WheelEvent 还有几个自己的属性。
deltaX:返回一个数值,表示滚轮的水平滚动量。
deltaY:返回一个数值,表示滚轮的垂直滚动量。
deltaZ:返回一个数值,表示滚轮的Z轴滚动量。
deltaMode:返回一个数值,表示滚动的单位,适用于上面三个属性。0表示像素,1表示行,2表示页。
- 浏览器提供一个WheelEvent构造函数,可以用来生成滚轮事件的实例。它接受两个参数,第一个是事件名称,第二个是配置对象。
var syntheticEvent = new WheelEvent("syntheticWheel", {"deltaX": 4, "deltaMode": 0});
(三) 键盘事件
(1)键盘事件用来描述键盘行为,主要有keydown、keypress、keyup三个事件。
-
keydown:按下键盘时触发该事件。
-
keypress:只要按下的键并非Ctrl、Alt、Shift和Meta,就接着触发keypress事件。
-
keyup:松开键盘时触发该事件。
(2) 如果用户一直按键不松开,就会连续触发键盘事件,触发的顺序如下。
keydown
keypress
keydown
keypress
(重复以上过程)
keyup
(3) 键盘事件使用 KeyboardEvent 对象表示,该对象继承了UIEvent和MouseEvent对象。浏览器提供KeyboardEvent构造函数,用来新建键盘事件的实例。
(4) altKey,ctrlKey,metaKey,shiftKey
- altKey:alt键
- ctrlKey:ctrl键
- metaKey:meta键(mac系统是一个四瓣的小花,windows系统是windows键)
- shiftKey:shift键
var inpu = document.getElementById('input');
var keyDown = function (e) {
console.log(e.ctrlKey, '是否按下了ctrl键')
console.log(e.altKey, '是否按下了alt键')
console.log(e.metaKey, '是否按下了win键')
console.log(e.shiftKey, '是否按下了shift键')
console.log(e.key,'e.key返回一个字符串,表示按下的键名')
// 这里要注意:keypress 事件中ctrlKey,altKey,shiftKey,metaKey事件是undefined
// 在keydown 和 keyup事件中是true和false
}
inpu.addEventListener('keydown', keyDown, false); // keydown事件,触发keyDoen监听函数
(5) key 属性
key属性返回一个字符串,表示按下的键名。
- 如果同时按下一个控制键和一个符号键,则返回符号键的键名。
比如,按下Ctrl+a,则返回a。
var inpu = document.getElementById('input');
var keyDown = function (e) {
console.log(e.key,'e.key返回一个字符串,表示按下的键名')
} // keypress事件的监听函数中,传入的参数keyboardEvent,没有ctrl,alt,meta,shift属性
inpu.addEventListener('keydown', keyDown, false); // keydown事件,触发keyDoen监听函数
(四) 进度事件
进度事件用来描述一个事件进展的过程,比如XMLHttpRequest对象发出的HTTP请求的过程、<img>、<audio>、<video>、<style>、<link>加载外部资源的过程。下载和上传都会发生进度事件。
abort事件:当进度事件被中止时触发。如果发生错误,导致进程中止,不会触发该事件。
-
error事件:由于错误导致资源无法加载时触发。
-
load事件:进度成功结束时触发。
-
oadstart事件:进度开始时触发。
-
loadend事件:进度停止时触发,发生顺序排在error事件\abort事件\load事件后面。
-
progress事件:当操作处于进度之中,由传输的数据块不断触发。
-
timeout事件:进度超过限时触发。
image.addEventListener('load', function(event) {
image.classList.add('finished');
});
image.addEventListener('error', function(event) {
image.style.display = 'none';
});
上面代码在图片元素加载完成后,为图片元素的class属性添加一个值“finished”。
如果加载失败,就把图片元素的样式设置为不显示。
-
有时候,图片加载会在脚本运行之前就完成,尤其是当脚本放置在网页底部的时候,因此有可能使得load和error事件的监听函数根本不会被执行。所以,比较可靠的方式,是用complete属性先判断一下是否加载完成。
-
由于DOM没有提供像complete属性那样的,判断是否发生加载错误的属性,所以error事件的监听函数最好放在img元素的HTML属性中,这样才能保证发生加载错误时百分之百会执行。
<img src="/wrong/url" onerror="this.style.display='none';" />
这样写能保证,发生加载错误时,onerror事件百分百会执行
(1) 进度事件使用ProgressEvent对象表示
ProgressEvent实例有以下属性。
-
lengthComputable:返回一个布尔值,表示当前进度是否具有可计算的长度。如果为false,就表示当前进度无法测量。
-
total:返回一个数值,表示当前进度的总长度。如果是通过HTTP下载某个资源,表示内容本身的长度,不含HTTP头部的长度。如果lengthComputable属性为false,则total属性就无法取得正确的值。
-
loaded:返回一个数值,表示当前进度已经完成的数量。该属性除以total属性,就可以得到目前进度的百分比。
(五) 拖拉事件
拖拉指的是,用户在某个对象上按下鼠标键不放,拖动它到另一个位置,然后释放鼠标键,将该对象放在那里。
拖拉的对象有好几种,包括Element节点、图片、链接、选中的文字等等。在HTML网页中,除了Element节点默认不可以拖拉,其他(图片、链接、选中的文字)都是可以直接拖拉的。为了让Element节点可拖拉,可以将该节点的draggable属性设为true。
- Element节点默认不可以拖拉,为了让Element节点默认可以拖拉,要将 draggable属性设为true
- draggable属性可用于任何Element节点,但是图片(img元素)和链接(a元素)不加这个属性,就可以拖拉。对于它们,用到这个属性的时候,往往是将其设为false,防止拖拉。
- 注意,一旦某个Element节点的draggable属性设为true,就无法再用鼠标选中该节点内部的文字或子节点了。
(六) 触摸事件
触摸API由三个对象组成。
-
Touch
Touch对象表示触摸点(一根手指或者一根触摸笔),用来描述触摸动作,包括位置、大小、形状、压力、目标元素等属性。 -
TouchList
有时,触摸动作由多个触摸点(多根手指或者多根触摸笔)组成,多个触摸点的集合由TouchList对象表示。 -
TouchEvent
TouchEvent对象代表由触摸引发的事件,只有触摸屏才会引发这一类事件。
(七) 表单事件
(1)input事件 ----------- 输入时触发
input事件当<input>、<textarea>的值发生变化时触发。此外,打开contenteditable属性的元素,只要值发生变化,也会触发input事件。
input事件的一个特点,就是会连续触发,比如用户每次按下一次按键,就会触发一次input事件。
(2) select事件 ----------- 选中里面值时 触发
select事件当在<input>、<textarea>中选中文本时触发。
(3) Change事件 -------- 值改变且失去焦点时 触发,分下面三种情况
Change事件当<input>、<select>、<textarea>的值发生变化时触发。
- 它与input事件的最大不同,就是不会连续触发,只有当全部修改完成时才会触发。
- 而且input事件必然会引发change事件。具体来说,分成以下几种情况。
激活单选框(radio)或复选框(checkbox)时触发。
用户提交时触发。比如,从下列列表(select)完成选择,在日期或文件输入框完成选择。
当文本框或textarea元素的值发生改变,并且丧失焦点时触发
(4) reset事件,submit事件
以下事件发生在表单对象上,而不是发生在表单的成员上。
- (1) reset事件
reset事件当表单重置(所有表单成员变回默认值)时触发。 - (2) submit事件
submit事件当表单数据向服务器提交时触发。注意,submit事件的发生对象是form元素,而不是button元素(即使它的类型是submit),因为提交的是表单,而不是按钮。
(八) 文档事件
(1) hashchange事件,popstate事件
以下事件与文档的URL变化相关。
(1) hashchange事件
hashchange事件在URL的hash部分(即#号后面的部分,包括#号)发生变化时触发。如果老式浏览器不支持该属性,可以通过定期检查location.hash属性,模拟该事件
- hashchange事件对象除了继承Event对象,还有oldURL属性和newURL属性,分别表示变化前后的URL。
(2) popstate事件
popstate事件在浏览器的history对象的当前记录发生显式切换时触发。注意,调用history.pushState()或history.replaceState(),并不会触发popstate事件。该事件只在用户在history记录之间显式切换时触发,比如鼠标点击“后退/前进”按钮,或者在脚本中调用history.back()、history.forward()、history.go()时触发。