进阶之事件这个要理解才行(二)
2、MouseEvent 接口概述
MouseEvent
接口代表所有鼠标事件所产生的对象都是MouseEvent
实例。此外,滚轮事件和拖拉事件也是MouseEvent
实例。
MouseEvent
接口继承了Event
接口,所以拥有Event
的所有属性和方法。它还有自己的属性和方法。
浏览器原生提供一个MouseEvent
构造函数,用于新建一个MouseEvent
实例。
var event = new MouseEvent(type, options);// 参数一,事件名称字符串;参数二,事件配置对象
MouseEvent
构造函数接受两个参数。第一个参数是字符串,表示事件名称;第二个参数是一个事件配置对象,该参数可选。除了Event
接口的实例配置属性,该对象可以配置以下属性,所有属性都是可选的。
screenX
:数值,鼠标相对于屏幕的水平位置(单位像素),默认值为0,设置该属性不会移动鼠标。screenY
:数值,鼠标相对于屏幕的垂直位置(单位像素),其他与screenX
相同。clientX
:数值,鼠标相对于程序窗口的水平位置(单位像素),默认值为0,设置该属性不会移动鼠标。clientY
:数值,鼠标相对于程序窗口的垂直位置(单位像素),其他与clientX
相同。ctrlKey
:布尔值,是否同时按下了 Ctrl 键,默认值为false
。shiftKey
:布尔值,是否同时按下了 Shift 键,默认值为false
。altKey
:布尔值,是否同时按下 Alt 键,默认值为false
。metaKey
:布尔值,是否同时按下 Meta 键(win键),默认值为false
。button
:数值,表示按下了哪一个鼠标按键,默认值为0
,表示按下主键(通常是鼠标的左键)或者当前事件没有定义这个属性;1
表示按下辅助键(通常是鼠标的中间键),2
表示按下次要键(通常是鼠标的右键)。buttons
:数值,表示按下了鼠标的哪些键,是一个三个比特位的二进制值,默认为0
(没有按下任何键)。1
(二进制001
)表示按下主键(通常是左键),2
(二进制010
)表示按下次要键(通常是右键),4
(二进制100
)表示按下辅助键(通常是中间键)。因此,如果返回3
(二进制011
)就表示同时按下了左键和右键。relatedTarget
:节点对象,表示事件的相关节点,默认为null
。mouseenter
和mouseover
事件时,表示鼠标刚刚离开的那个元素节点;mouseout
和mouseleave
事件时,表示鼠标正在进入的那个元素节点。
下面是一个例子。
var event = new MouseEvent('click2', {
'bubbles': true,
'cancelable': true
});
var cb = document.getElementById('checkbox');
cb.addEventListener('click2',function(){ // 绑定事件监听函数
console.log(22) // 被执行
})
cb.dispatchEvent(event);// 触发事件
上面代码生成一个鼠标点击事件,并触发该事件。
3、MouseEvent 接口的实例属性
3.1 MouseEvent.altKey,MouseEvent.ctrlKey,MouseEvent.metaKey,MouseEvent.shiftKey
MouseEvent.altKey
、MouseEvent.ctrlKey
、MouseEvent.metaKey
、MouseEvent.shiftKey
这四个属性都返回一个布尔值,表示事件发生时,是否按下对应的键。它们都是只读属性。
altKey
属性:Alt 键ctrlKey
属性:Ctrl 键metaKey
属性:Meta 键(Mac 键盘是一个四瓣的小花,Windows 键盘是 Windows 键)shiftKey
属性:Shift 键
// HTML 代码如下
// <body onclick="showKey(event)">
function showKey(e) {
console.log('ALT key pressed: ' + e.altKey);
console.log('CTRL key pressed: ' + e.ctrlKey);
console.log('META key pressed: ' + e.metaKey);
console.log('SHIFT key pressed: ' + e.shiftKey);
}
上面代码中,点击网页会输出是否同时按下对应的键。
3.2 MouseEvent.button 鼠标的哪个键,MouseEvent.buttons同时按哪些键
MouseEvent.button
属性返回一个数值,表示事件发生时按下了鼠标的哪个键。该属性只读。
- 0:按下主键(通常是左键),或者该事件没有初始化这个属性(比如
mousemove
事件)。 - 1:按下辅助键(通常是中键或者滚轮键)。
- 2:按下次键(通常是右键)。
// HTML 代码为
// <button onmouseup="whichButton(event)">点击</button>
var whichButton = function (e) {
switch (e.button) {
case 0:
console.log('Left button clicked.');
break;
case 1:
console.log('Middle button clicked.');
break;
case 2:
console.log('Right button clicked.');
break;
default:
console.log('Unexpected code: ' + e.button);
}
}
MouseEvent.buttons
属性返回一个三个比特位的值,表示同时按下了哪些键。它用来处理同时按下多个鼠标键的情况。该属性只读。
- 1:二进制为
001
(十进制的1),表示按下左键。 - 2:二进制为
010
(十进制的2),表示按下右键。 - 4:二进制为
100
(十进制的4),表示按下中键或滚轮键。
同时按下多个键的时候,每个按下的键对应的比特位都会有值。比如,同时按下左键和右键,会返回3(二进制为011)。
document.body.addEventListener('mousemove',function(e){ // 注意,用click时一直都是0
console.log(e.buttons)
})
// 未按下任何键时是 0
// 按下左键 1 (001)
// 按下右键 2 (010)
// 按下中键 4 (100)
// 按下左键和右键 3 (011)
// 按下左键和中键 5 (101)
// 按下右键和中键 6 (110)
// 按下左、中、右键 7 (111)
3.3 MouseEvent.clientX 相对浏览器X坐标,MouseEvent.clientY 相对浏览器Y坐标
MouseEvent.clientX
属性返回鼠标位置相对于浏览器窗口左上角的水平坐标(单位像素),MouseEvent.clientY
属性返回垂直坐标。这两个属性都是只读属性。
// HTML 代码为
// <body onmousedown="showCoords(event)">
function showCoords(evt){
console.log(
'clientX value: ' + evt.clientX + '\n' +
'clientY value: ' + evt.clientY + '\n'
);
}
这两个属性还分别有一个别名MouseEvent.x
和MouseEvent.y
。
3.4 MouseEvent.movementX 上一个鼠标经过事件的X距离,MouseEvent.movementY 上一个鼠标经过事件的Y距离
MouseEvent.movementX
属性返回当前位置与上一个mousemove
事件之间的水平距离(单位像素)。数值上,它等于下面的计算公式。
currentEvent.movementX = currentEvent.screenX - previousEvent.screenX
MouseEvent.movementY
属性返回当前位置与上一个mousemove
事件之间的垂直距离(单位像素)。数值上,它等于下面的计算公式。
currentEvent.movementY = currentEvent.screenY - previousEvent.screenY。
这两个属性都是只读属性。
3.5 MouseEvent.screenX 相对屏幕X坐标,MouseEvent.screenY 相对屏幕Y坐标
MouseEvent.screenX
属性返回鼠标位置相对于屏幕左上角的水平坐标(单位像素),MouseEvent.screenY
属性返回垂直坐标。这两个属性都是只读属性。
// HTML 代码如下
// <body onmousedown="showCoords(event)">
function showCoords(evt) {
console.log(
'screenX value: ' + evt.screenX + '\n',
'screenY value: ' + evt.screenY + '\n'
);
}
3.6 MouseEvent.offsetX 偏移量X,MouseEvent.offsetY 偏移量Y
MouseEvent.offsetX
属性返回鼠标位置与目标节点左侧的padding
边缘的水平距离(单位像素),MouseEvent.offsetY
属性返回与目标节点上方的padding
边缘的垂直距离。这两个属性都是只读属性。
/* HTML 代码如下
<style>
p {
width: 100px;
height: 100px;
padding: 100px;
}
</style>
<p>Hello</p>
*/
var p = document.querySelector('p');
p.addEventListener(
'click',
function (e) {
console.log(e.offsetX); // 包含padding
console.log(e.offsetY);
},
false
);
上面代码中,鼠标如果在p
元素的中心位置点击,会返回150 150
。因此中心位置距离左侧和上方的padding
边缘,等于padding
的宽度(100像素)加上元素内容区域一半的宽度(50像素)。
3.7 MouseEvent.pageX 文档X坐标,MouseEvent.pageY 文档Y坐标
MouseEvent.pageX
属性返回鼠标位置与文档左侧边缘的距离(单位像素),MouseEvent.pageY
属性返回与文档上侧边缘的距离(单位像素)。它们的返回值都包括文档不可见的部分。这两个属性都是只读。
/* HTML 代码如下
<style>
body {
height: 2000px;
}
</style>
*/
document.body.addEventListener(
'click',
function (e) {
console.log(e.pageX);
console.log(e.pageY);
},
false
);
上面代码中,页面高度为2000像素,会产生垂直滚动条。滚动到页面底部,点击鼠标输出的pageY
值会接近2000。
3.8 MouseEvent.relatedTarget 事件的相关节点
MouseEvent.relatedTarget
属性返回事件的相关节点。对于那些没有相关节点的事件,该属性返回null
。该属性只读。
下表列出不同事件的target
属性值和relatedTarget
属性值义。
事件名称 | target 属性 | relatedTarget 属性 |
---|---|---|
focusin | 接受焦点的节点 | 丧失焦点的节点 |
focusout | 丧失焦点的节点 | 接受焦点的节点 |
mouseenter | 将要进入的节点 | 将要离开的节点 |
mouseleave | 将要离开的节点 | 将要进入的节点 |
mouseout | 将要离开的节点 | 将要进入的节点 |
mouseover | 将要进入的节点 | 将要离开的节点 |
dragenter | 将要进入的节点 | 将要离开的节点 |
dragexit | 将要离开的节点 | 将要进入的节点 |
下面是一个例子。
/*
HTML 代码如下
<div id="outer" style="height:50px;width:50px;border-width:1px solid black;">
<div id="inner" style="height:25px;width:25px;border:1px solid black;"></div>
</div>
*/
var inner = document.getElementById('inner');
inner.addEventListener('mouseover', function (event) {
console.log('进入' + event.target.id + ' 离开' + event.relatedTarget.id);
}, false);
inner.addEventListener('mouseenter', function (event) {
console.log('进入' + event.target.id + ' 离开' + event.relatedTarget.id);
});
inner.addEventListener('mouseout', function () {
console.log('离开' + event.target.id + ' 进入' + event.relatedTarget.id);
});
inner.addEventListener("mouseleave", function (){
console.log('离开' + event.target.id + ' 进入' + event.relatedTarget.id);
});
// 鼠标从 outer 进入inner,输出
// 进入inner 离开outer
// 进入inner 离开outer
// 鼠标从 inner进入 outer,输出
// 离开inner 进入outer
// 离开inner 进入outer
4、MouseEvent 接口的实例方法
4.1 MouseEvent.getModifierState() 是否按下指定功能键
MouseEvent.getModifierState
方法返回一个布尔值,表示有没有按下特定的功能键。它的参数是一个表示功能键的字符串。
document.addEventListener('click', function (e) {
console.log(e.getModifierState('CapsLock'));
}, false);
上面的代码可以了解用户是否按下了大写键。
5、WheelEvent 接口 (滚轮)
5.1 概述
WheelEvent 接口继承了 MouseEvent 实例,代表鼠标滚轮事件的实例对象。目前,鼠标滚轮相关的事件只有一个wheel
事件,用户滚动鼠标的滚轮,就生成这个事件的实例。
浏览器原生提供WheelEvent()
构造函数,用来生成WheelEvent
实例。
var wheelEvent = new WheelEvent(type, options);
WheelEvent()
构造函数可以接受两个参数,第一个是字符串,表示事件类型,对于滚轮事件来说,这个值目前只能是wheel
。第二个参数是事件的配置对象。该对象的属性除了Event
、UIEvent
的配置属性以外,还可以接受以下几个属性,所有属性都是可选的。
deltaX
:数值,表示滚轮的水平滚动量,默认值是 0.0。deltaY
:数值,表示滚轮的垂直滚动量,默认值是 0.0。deltaZ
:数值,表示滚轮的 Z 轴滚动量,默认值是 0.0。deltaMode
:数值,表示相关的滚动事件的单位,适用于上面三个属性。0
表示滚动单位为像素,1
表示单位为行,2
表示单位为页,默认为0
。
5.2 实例属性
WheelEvent
事件实例除了具有Event
和MouseEvent
的实例属性和实例方法,还有一些自己的实例属性,但是没有自己的实例方法。
下面的属性都是只读属性。
WheelEvent.deltaX
:数值,表示滚轮的水平滚动量。WheelEvent.deltaY
:数值,表示滚轮的垂直滚动量。WheelEvent.deltaZ
:数值,表示滚轮的 Z 轴滚动量。WheelEvent.deltaMode
:数值,表示上面三个属性的单位,0
是像素,1
是行,2
是页。
五、键盘事件
1、键盘事件的种类
键盘事件由用户击打键盘触发,主要有keydown
、keypress
、keyup
三个事件,它们都继承了KeyboardEvent
接口。
keydown
:按下键盘时触发。【按下】keypress
:按下有值的键时触发,即按下 Ctrl、Alt、Shift、Meta 这样无值的键,这个事件不会触发。对于有值的键,按下时先触发keydown
事件,再触发这个事件。【按下有值的键】keyup
:松开键盘时触发该事件。【松开】
如果用户一直按键不松开,就会连续触发键盘事件,触发的顺序如下。
- keydown
- keypress
- keydown
- keypress
- ...(重复以上过程)
- keyup
2、KeyboardEvent 接口概述
KeyboardEvent
接口用来描述用户与键盘的互动。这个接口继承了Event
接口,并且定义了自己的实例属性和实例方法。
浏览器原生提供KeyboardEvent
构造函数,用来新建键盘事件的实例。
new KeyboardEvent(type, options) // 参数一,事件类型;参数二,事件配置对象
KeyboardEvent
构造函数接受两个参数。第一个参数是字符串,表示事件类型;第二个参数是一个事件配置对象,该参数可选。除了Event
接口提供的属性,还可以配置以下字段,它们都是可选。
key
:字符串,当前按下的键,默认为空字符串。【键名】code
:字符串,表示当前按下的键的字符串形式,默认为空字符串。【键码】location
:整数,当前按下的键的位置,默认为0
。ctrlKey
:布尔值,是否按下 Ctrl 键,默认为false
。shiftKey
:布尔值,是否按下 Shift 键,默认为false
。altKey
:布尔值,是否按下 Alt 键,默认为false
。metaKey
:布尔值,是否按下 Meta 键,默认为false
。repeat
:布尔值,是否重复按键,默认为false
。
3、KeyboardEvent 的实例属性
3.1 KeyboardEvent.altKey,KeyboardEvent.ctrlKey,KeyboardEvent.metaKey,KeyboardEvent.shiftKey 【是否按下对应键,布尔值】
以下属性都是只读属性,返回一个布尔值,表示是否按下对应的键。
KeyboardEvent.altKey
:是否按下 Alt 键KeyboardEvent.ctrlKey
:是否按下 Ctrl 键KeyboardEvent.metaKey
:是否按下 meta 键(Mac 系统是一个四瓣的小花,Windows 系统是 windows 键)KeyboardEvent.shiftKey
:是否按下 Shift 键
下面是一个示例。
function showChar(e) {
console.log('ALT: ' + e.altKey);
console.log('CTRL: ' + e.ctrlKey);
console.log('Meta: ' + e.metaKey);
console.log('Shift: ' + e.shiftKey);
}
document.body.addEventListener('keydown', showChar, false);
3.2 KeyboardEvent.code 键码
KeyboardEvent.code
属性返回一个字符串,表示当前按下的键的字符串形式。该属性只读。
下面是一些常用键的字符串形式,其他键请查文档。
- 数字键0 - 9:返回
digital0
-digital9
- 字母键A - z:返回
KeyA
-KeyZ
- 功能键F1 - F12:返回
F1
-F12
- 方向键:返回
ArrowDown
、ArrowUp
、ArrowLeft
、ArrowRight
- Alt 键:返回
AltLeft
或AltRight
- Shift 键:返回
ShiftLeft
或ShiftRight
- Ctrl 键:返回
ControlLeft
或ControlRight
3.3 KeyboardEvent.key 键名
KeyboardEvent.key
属性返回一个字符串,表示按下的键名。该属性只读。
如果按下的键代表可打印字符,则返回这个字符,比如数字、字母。
如果按下的键代表不可打印的特殊字符,则返回预定义的键值,比如 Backspace,Tab,Enter,Shift,Control,Alt,CapsLock,Esc,Spacebar,PageUp,PageDown,End,Home,Left,Right,Up,Down,PrintScreen,Insert,Del,Win,F1~F12,NumLock,Scroll 等。
如果同时按下一个控制键和一个符号键,则返回符号键的键名。比如,按下 Ctrl + a,则返回a
;按下 Shift + a,则返回大写的A
。
如果无法识别键名,返回字符串Unidentified
。
3.4 KeyboardEvent.location 键处于哪个位置,整数
KeyboardEvent.location
属性返回一个整数,表示按下的键处在键盘的哪一个区域。它可能取以下值。
-
0:处在键盘的主区域,或者无法判断处于哪一个区域。
-
1:处在键盘的左侧,只适用那些有两个位置的键(比如 Ctrl 和 Shift 键)。
-
2:处在键盘的右侧,只适用那些有两个位置的键(比如 Ctrl 和 Shift 键)。
-
3:处在数字小键盘。
3.5 KeyboardEvent.repeat 是否长按
KeyboardEvent.repeat
返回一个布尔值,代表该键是否被按着不放,以便判断是否重复这个键,即浏览器会持续触发keydown
和keypress
事件,直到用户松开手为止。
4、KeyboardEvent 的实例方法
4.1 KeyboardEvent.getModifierState() 是否按下指定功能键
KeyboardEvent.getModifierState()
方法返回一个布尔值,表示是否按下或激活指定的功能键。它的常用参数如下。
Alt
:Alt 键CapsLock
:大写锁定键Control
:Ctrl 键Meta
:Meta 键NumLock
:数字键盘开关键Shift
:Shift 键
if (
event.getModifierState('Control') +
event.getModifierState('Alt') +
event.getModifierState('Meta') > 1
) {
return;
}
上面代码表示,只要Control
、Alt
、Meta
里面,同时按下任意两个或两个以上的键就返回。
六、进度事件
1、进度事件的种类
进度事件用来描述资源加载的进度,主要由 AJAX 请求、<img>
、<audio>
、<video>
、<style>
、<link>
等外部资源的加载触发,继承了ProgressEvent
接口。它主要包含以下几种事件。
abort
:外部资源中止加载时(比如用户取消)触发。如果发生错误导致中止,不会触发该事件。【中止加载】error
:由于错误导致外部资源无法加载时触发。【加载错误】load
:外部资源加载成功时触发。【加载成功】loadstart
:外部资源开始加载时触发。【开始加载】loadend
:外部资源停止加载时触发,发生顺序排在error
、abort
、load
等事件的后面。【停止加载】progress
:外部资源加载过程中不断触发。【加载中,不断触发】timeout
:加载超时时触发。【加载超时】
注意,除了资源下载,文件上传也存在这些事件。
下面是一个例子。
image.addEventListener('load', function (event) { // 加载成功
image.classList.add('finished');
});
image.addEventListener('error', function (event) { // 加载出错
image.style.display = 'none';
});
上面代码在图片元素加载完成后,为图片元素添加一个finished
的 Class。如果加载失败,就把图片元素的样式设置为不显示。
有时候,图片加载会在脚本运行之前就完成,尤其是当脚本放置在网页底部的时候,因此有可能load
和error
事件的监听函数根本不会执行。所以,比较可靠的方式,是用complete
属性先判断一下是否加载完成。
function loaded() {
// ...
}
if (image.complete) { // 是否加载完成
loaded();
} else {
image.addEventListener('load', loaded); // 加载成功事件
}
由于 DOM 的元素节点没有提供是否加载错误的属性,所以error
事件的监听函数最好放在<img>
元素的 HTML 代码中,这样才能保证发生加载错误时百分之百会执行。
<img src="/wrong/url" onerror="this.style.display='none';" />
loadend
事件的监听函数,可以用来取代abort
事件、load
事件、error
事件的监听函数,因为它总是在这些事件之后发生。
req.addEventListener('loadend', loadEnd, false);
function loadEnd(e) {
console.log('传输结束,成功失败未知');
}
loadend
事件本身不提供关于进度结束的原因,但可以用它来做所有加载结束场景都需要做的一些操作。
另外,error
事件有一个特殊的性质,就是不会冒泡。所以,子元素的error
事件,不会触发父元素的error
事件监听函数。
2、ProgressEvent 接口
2.1 概述
ProgressEvent
接口主要用来描述外部资源加载的进度,比如 AJAX 加载、<img>
、<video>
、<style>
、<link>
等外部资源加载。进度相关的事件都继承了这个接口。这个接口继承了Event接口。
浏览器原生提供了ProgressEvent()
构造函数,用来生成事件实例。
new ProgressEvent(type, options) // 参数一,事件类型;参数二,配置对象
ProgressEvent()
构造函数接受两个参数。第一个参数是字符串,表示事件的类型,这个参数是必须的。第二个参数是一个配置对象,表示事件的属性,该参数可选。配置对象除了可以使用Event
接口的配置属性,还可以使用下面的属性,所有这些属性都是可选的。
lengthComputable
:布尔值,表示加载的总量是否可以计算,默认是false
。loaded
:整数,表示已经加载的量,默认是0
。total
:整数,表示需要加载的总量,默认是0
。
2.2 ProgressEvent的实例属性。
ProgressEvent.lengthComputable
总量是否可以计算ProgressEvent.loaded
已加载的量ProgressEvent.total
需要加载的总量
如果ProgressEvent.lengthComputable
为false
,ProgressEvent.total
实际上是没有意义的。
下面是一个例子。
var p = new ProgressEvent('load', {
lengthComputable: true,
loaded: 30,
total: 100,
});
document.body.addEventListener('load', function (e) {
console.log('已经加载:' + (e.loaded / e.total) * 100 + '%');
});
document.body.dispatchEvent(p);
// 已经加载:30%
上面代码先构造一个load
事件,抛出后被监听函数捕捉到。
下面是一个实际的例子。
var xhr = new XMLHttpRequest();
xhr.addEventListener('progress', updateProgress, false); // 加载中
xhr.addEventListener('load', transferComplete, false); // 加载成功
xhr.addEventListener('error', transferFailed, false); // 加载错误
xhr.addEventListener('abort', transferCanceled, false); // 中止加载
xhr.open();
function updateProgress(e) { // 加载中
if (e.lengthComputable) { // 是否可以计算总量
var percentComplete = e.loaded / e.total; // 加载进度计算
} else {
console.log('不能计算进度');
}
}
function transferComplete(e) { // 加载成功
console.log('传输结束');
}
function transferFailed(evt) { // 加载错误
console.log('传输过程中发生错误');
}
function transferCanceled(evt) { // 中止加载
console.log('用户取消了传输');
}
上面是下载过程的进度事件,还存在上传过程的进度事件。这时所有监听函数都要放在XMLHttpRequest.upload
对象上面。
var xhr = new XMLHttpRequest();
xhr.upload.addEventListener('progress', updateProgress, false);
xhr.upload.addEventListener('load', transferComplete, false);
xhr.upload.addEventListener('error', transferFailed, false);
xhr.upload.addEventListener('abort', transferCanceled, false);
xhr.open();
七、表单事件
1、表单事件的种类
1.1 input 事件 (值发生变化触发,会连续)
input
事件当<input>
、<select>
、<textarea>
的值发生变化时触发。对于复选框(<input type=checkbox>
)或单选框(<input type=radio>
),用户改变选项时,也会触发这个事件。另外,对于打开contenteditable
属性的元素,只要值发生变化,也会触发input
事件。
input
事件的一个特点,就是会连续触发,比如用户每按下一次按键,就会触发一次input
事件。
input
事件对象继承了InputEvent
接口。
该事件跟change
事件很像,不同之处在于*input
事件在元素的值发生变化后立即发生*,而change
在元素失去焦点时发生,而内容此时可能已经变化多次。也就是说,如果有连续变化,input
事件会触发多次,而change
事件只在失去焦点时触发一次。
下面是<select>
元素的例子。
/* HTML 代码如下
<select id="mySelect">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
*/
function inputHandler(e) {
console.log(e.target.value)
}
var mySelect = document.querySelector('#mySelect');
mySelect.addEventListener('input', inputHandler);
上面代码中,改变下拉框选项时,会触发input
事件,从而执行回调函数inputHandler
。
1.2 select 事件 (选中文本时触发)
select
事件当在<input>
、<textarea>
里面选中文本时触发。
// HTML 代码如下
// <input id="test" type="text" value="Select me!" />
var elem = document.getElementById('test');
elem.addEventListener('select', function (e) {
console.log(e.type); // "select" 事件类型
var _target = e.target;
console.log(_target.value); // 文本框的全部值
console.log(_target.selectionDirection); // 选择的方向:'forward'正向、'backward'反向
console.log(_target.selectionStart); // 开始选择的索引
console.log(_target.selectionEnd); // 结束选择的索引
// 注意:开始和结束索引是不分选择方向的,开始的索引一直是靠前的
console.log(_target.value.slice(_target.selectionStart, _target.selectionEnd)) // 选中的那部分字符串
}, false);
选中的文本可以通过event.target
元素的selectionDirection
、selectionEnd
、selectionStart
和value
属性拿到。
1.3 change 事件 (值发生变化时触发,单次)
change
事件当<input>
、<select>
、<textarea>
的值发生变化时触发。它与input
事件的最大不同,就是不会连续触发,只有当全部修改完成时才会触发,另一方面input
事件必然伴随change
事件。具体来说,分成以下几种情况。
- 激活单选框(radio)或复选框(checkbox)时触发。
- 用户提交时触发。比如,从下列列表(select)完成选择,在日期或文件输入框完成选择。
- 当文本框或
<textarea>
元素的值发生改变,并且丧失焦点时触发。
下面是一个例子。
// HTML 代码如下
// <select size="1" onchange="changeEventHandler(event);">
// <option>chocolate</option>
// <option>strawberry</option>
// <option>vanilla</option>
// </select>
function changeEventHandler(event) {
console.log(event.target.value);
}
如果比较一下上面input
事件的例子,你会发现对于<select>
元素来说,input
和change
事件基本是等价的。
1.4 invalid 事件 (表单提交不满足条件触发)
用户提交表单时,如果表单元素的值不满足校验条件,就会触发invalid
事件。
<form>
<input type="text" required oninvalid="console.log('invalid input')" />
<button type="submit">提交</button>
</form>
上面代码中,输入框是必填的。如果不填,用户点击按钮提交时,就会触发输入框的invalid
事件,导致提交被取消。
1.5 reset 事件(重置),submit 事件(提交)
reset
事件当表单重置(所有表单成员变回默认值)时触发。
submit
事件当表单数据向服务器提交时触发。
注意,这两个事件发生在表单对象<form>
上,而不是发生在表单的成员上,因为提交的是表单,而不是表单成员。
<form onreset="console.log('触发了重置事件')" onsubmit="console.log('触发了提交事件')" name="input" action="html_form_action.php" method="get">
<input type="text" name="lname" value="Duck">
<button type="reset">重置</button>
<button type="submit">提交</button>
</form>
2、InputEvent 接口(input事件的实例)
InputEvent
接口主要用来描述input
事件的实例。该接口继承了Event
接口,还定义了一些自己的实例属性和实例方法。
浏览器原生提供InputEvent()
构造函数,用来生成实例对象。
new InputEvent(type, options) // 参数一,事件名称;参数二,配置对象
InputEvent
构造函数可以接受两个参数。第一个参数是字符串,表示事件名称,该参数是必需的。第二个参数是一个配置对象,用来设置事件实例的属性,该参数是可选的。配置对象的字段除了Event
构造函数的配置属性,还可以设置下面的字段,这些字段都是可选的。
inputType
:字符串,表示发生变更的类型(详见下文)。data
:字符串,表示插入的字符串。如果没有插入的字符串(比如删除操作),则返回null
或空字符串。dataTransfer
:返回一个 DataTransfer 对象实例,该属性通常只在输入框接受富文本输入时有效。
InputEvent
的实例属性主要就是上面三个属性,这三个实例属性都是只读的。
(1)InputEvent.data 变动的那部分内容
InputEvent.data
属性返回一个字符串,表示变动的内容。
// HTML 代码如下
// <input type="text" id="myInput">
var input = document.getElementById('myInput');
input.addEventListener('input', myFunction, false);
function myFunction(e) {
console.log(e.data);
}
上面代码中,如果手动在输入框里面输入abc
,控制台会先输出a
,再在下一行输出b
,再在下一行输出c
。然后选中abc
,一次性将它们删除,控制台会输出null
或一个空字符串。
(2)InputEvent.inputType 变更类型
InputEvent.inputType
属性返回一个字符串,表示字符串发生变更的类型。
对于常见情况,Chrome 浏览器的返回值如下。完整列表可以参考文档。
- 手动插入文本:
insertText
- 粘贴插入文本:
insertFromPaste
- 向后删除:
deleteContentBackward
- 向前删除:
deleteContentForward
(3)InputEvent.dataTransfer
InputEvent.dataTransfer
属性返回一个 DataTransfer 实例。该属性只在文本框接受粘贴内容(insertFromPaste)或拖拽内容(insertFromDrop
)时才有效。
- 点赞
- 收藏
- 关注作者
评论(0)