表单事件
一、事件种类
input事件
当<input>
、<select>
、<textarea>
的值发生变化时触发。
input
事件的一个特点,就是会连续触发,比如用户每按下一次按键,就会触发一次input
事件。
select事件
当在<input>
、<textarea>
里面选中文本时触发。
change事件
当<input>
、<select>
、<textarea>
的值发生变化时触发。
invalid事件
用户提交表单时,如果表单元素的值不满足校验条件,就会触发invalid
事件。
<form>
<input type="text" required oninvalid="console.log('invalid input')" />
<button type="submit">提交</button>
</form>
复制代码
上面代码中,输入框是必填的。如果不填,用户点击按钮提交时,就会触发输入框的invalid事件,导致提交被取消。
reset 事件 submit 事件
rese
t事件当表单重置(所有表单成员变回默认值)时触发。
submit
事件当表单数据向服务器提交时触发。注意,submit
事件的发生对象是<form>
元素,而不是<button>
元素,因为提交的是表单,而不是按钮。
二、 InputEvent 接口
InputEvent.data
返回一个字符串,表示变动的内容。InputEvent.inoutType
返回一个字符串,表示字符串发生变更的类型InputEvent.dataTransfer
返回一个 DataTransfer 实例。该属性只在文本框接受粘贴内容(insertFromPaste)或拖拽内容(insertFromDrop)时才有效。
触摸事件
浏览器的触摸API由三部分组成:
Touch
:一个触点TouchList
:多个触摸点的集合ToucheEvent
:触摸引发的事件实例
Touch 接口
实例属性
-
Touch.identifier
返回一个整数,表示触摸点的位移ID。这个值在整个触摸过程保持不变,直到触摸事件结束。 -
Touch.screenX
属性和Touch.screenY
属性,分别表示触摸点相对于屏幕左上角的横坐标和纵坐标,与页面是否滚动无关。 -
Touch.clientX
属性和Touch.clientY
属性,分别表示触摸点相对于浏览器视口左上角的横坐标和纵坐标,与页面是否滚动无关。 -
Touch.pageX
属性和Touch.pageY
属性,分别表示触摸点相对于当前页面左上角的横坐标和纵坐标,包含了页面滚动带来的位移。 -
Touch.radiusX
属性和Touch.radiusY
属性,分别返回触摸点周围受到影响的椭圆范围的X
轴半径和Y
轴半径,单位为像素。乘以2
就可以得到触摸范围的宽度和高度。 -
Touch.rotationAngle
属性表示触摸区域的椭圆的旋转角度,单位为度数,在0
到90
度之间。 -
Touch.force
属性返回一个0到1之间的数值,表示触摸压力。0代表没有压力,1代表硬件所能识别的最大压力。 -
Touch.target
返回一个元素节点,代表触摸发生时所在的那个元素节点。
TouchList接口
表示一组触摸点的集合,他们的实例是一个类数组对象。用户用三根手指触摸,产生的TouchList实例就会包含三个成员,每根手指的触摸点对应一个Touch实例对象。
实例主要通过触摸事件的TouchEvent.touches
、TouchEvent.changedTouches
、TouchEvent.targetTouches
这几个属性获取。
触摸事件种类
touchstart
:用户开始触摸时触发tauchend
:用户不再接触触摸屏时触发touchmove
:用户移动触摸点时触发touchcancel
:触摸点取消时触发,比如在触摸区域跳出一个模态窗口(modal window)、触摸点离开了文档区域(进入浏览器菜单栏)、用户的触摸点太多,超过了支持的上限(自动取消早先的触摸点)。
拖拉事件
一、事件种类
drag
:拖拉过程中,在被拖拉的节点上持续触发dragStart
:开始拖拉时,在被拖拉的节点上触发dragend
:拖拉结束时触发dragenter
:拖拉进入当前节点时,在当前节点上触发一次。dragover
:脱拉到当前节点上方时,在当前节点上持续触发dragleave
:拖拉操作离开当前节点范围时,在当前节点上触发drop
:被拖拉的节点或被选中的文本,释放到目标节点时,在目标节点上触发
/* HTML 代码如下
<div class="dropzone">
<div id="draggable" draggable="true">
该节点可拖拉
</div>
</div>
<div class="dropzone"></div>
<div class="dropzone"></div>
<div class="dropzone"></div>
*/
// 被拖拉节点
var dragged;
document.addEventListener('dragstart', function (event) {
// 保存被拖拉节点
dragged = event.target;
// 被拖拉节点的背景色变透明
event.target.style.opacity = 0.5;
}, false);
document.addEventListener('dragend', function (event) {
// 被拖拉节点的背景色恢复正常
event.target.style.opacity = '';
}, false);
document.addEventListener('dragover', function (event) {
// 防止拖拉效果被重置,允许被拖拉的节点放入目标节点
event.preventDefault();
}, false);
document.addEventListener('dragenter', function (event) {
// 目标节点的背景色变紫色
// 由于该事件会冒泡,所以要过滤节点
if (event.target.className === 'dropzone') {
event.target.style.background = 'purple';
}
}, false);
document.addEventListener('dragleave', function( event ) {
// 目标节点的背景色恢复原样
if (event.target.className === 'dropzone') {
event.target.style.background = '';
}
}, false);
document.addEventListener('drop', function( event ) {
// 防止事件默认行为(比如某些元素节点上可以打开链接),
event.preventDefault();
if (event.target.className === 'dropzone') {
// 恢复目标节点背景色
event.target.style.background = '';
// 将被拖拉节点插入目标节点
dragged.parentNode.removeChild(dragged);
event.target.appendChild( dragged );
}
}, false);
复制代码
关于拖拉事件,注意以下几点:
- 拖拉过程只触发以上这些事件,尽管鼠标在移动,但是鼠标事件不会触发
- 将文件从操作系统拉进浏览器,不会触发
dragstart
和dragend
事件 dragenter
和dragover
事件的监听函数,用来取出拖拉数据。由于网页的大部分区域不适合作为放下拖拉元素的目标几点,所以这两个事件的默认设置为当前节点不允许接受被拖拉的元素,如果想要在目标节点上放下的数据,首先必须阻止这两个事件的默认行为。
二、DataTransfer 接口
所有的拖拉事件的实例都一个DragEvent.dataTransfer
属性,用来读写需要传递的数据
三、DataTransfer的实例属性
DataTransfer.dropEffect
用来设置放下(drop)被拖动节点时的效果,会影响到拖拉经过相关区域时鼠标的形状。可取下面的值:
-
copy:复制被拖动的节点
-
move:移动被拖拉的节点
-
link:创建指向被拖拉的节点的链接
-
none:无法放下被拖拉的节点
dropEffect
属性一般在dragenter
和dragover
事件的监听函数中设置,对于dragstart
、drag
、dragleave
这三个事件,该属性不起作用。
DataTransfer.effectAllowed
属性设置本次拖拉中允许的效果,可能的取值:
- copy:复制被拖拉的节点
- move:移动被拖拉的节点
- link:创建指向被拖拉节点的链接
- copyLink:允许copy或link
- copyMove:允许copy或move
- linkMove:允许link或move
- all:允许所有效果
- none:无法放下被拖拉的节点
- uninitialized:默认值,等同于all
如果某种效果是不允许的,用户就无法在目标节点中达成这种效果。
dragstart
事件的监听函数,可以用来设置这个属性。其他事件的监听函数里面设置这个属性是无效的。
DataTransfer.files
属性是一个 FileList 对象,包含一组本地文件,可以用来在拖拉操作中传送。如果本次拖拉不涉及文件,则该属性为空的 FileList 对象。
// HTML 代码如下
// <div id="output" style="min-height: 200px;border: 1px solid black;">
// 文件拖拉到这里
// </div>
var div = document.getElementById('output');
div.addEventListener("dragenter", function( event ) {
div.textContent = '';
event.stopPropagation();
event.preventDefault();
}, false);
div.addEventListener("dragover", function( event ) {
event.stopPropagation();
event.preventDefault();
}, false);
div.addEventListener("drop", function( event ) {
event.stopPropagation();
event.preventDefault();
var files = event.dataTransfer.files;
for (var i = 0; i < files.length; i++) {
div.textContent += files[i].name + ' ' + files[i].size + '字节\n';
}
}, false);
复制代码
上面代码中,通过dataTransfer.files
属性读取被拖拉的文件的信息。如果想要读取文件内容,就要使用FileReader
对象。
div.addEventListener('drop', function(e) {
e.preventDefault();
e.stopPropagation();
var fileList = e.dataTransfer.files;
if (fileList.length > 0) {
var file = fileList[0];
var reader = new FileReader();
reader.onloadend = function(e) {
if (e.target.readyState === FileReader.DONE) {
var content = reader.result;
div.innerHTML = 'File: ' + file.name + '\n\n' + content;
}
}
reader.readAsBinaryString(file);
}
});
复制代码
DataTransfer.types
属性是一个只读的数组,每个成员是一个字符串,里面是拖拉的数据格式(通常是 MIME 值)。比如,如果拖拉的是文字,对应的成员就是text/plain。
四、DataTransfer 的实例方法
一、资源事件
DataTransfer.setData()
方法用来设置拖拉事件所带有的数据。该方法没有返回值。DataTransfer.getData()
方法接受一个字符串(表示数据类型)作为参数,返回事件所带的指定类型的数据(通常是用setData方法添加的数据)。DataTransfer.clearData()
方法接受一个字符串(表示数据类型)作为参数,删除事件所带的指定类型的数据。如果没有指定类型,则删除所有数据。如果指定类型不存在,则调用该方法不会产生任何效果。DataTransfer.setDragImage()
方法可以自定义跟随鼠标一起移动的图片。它接受三个参数。第一个是节点或者节点,如果省略或为null,则使用被拖动的节点的外观;第二个和第三个参数为鼠标相对于该图片左上角的横坐标和右坐标。
其他事件
beforeunload事件
在窗口、文档、各种资源将要卸载前触发。它可以用来防止用户不小心卸载资源。
unload 事件
在窗口关闭或者document
对象将要卸载时触发。它的触发顺序排在beforeunload
、pagehide
事件后面。
load 事件,error 事件
load
事件在页面或某个资源加载成功时触发。error
事件是在页面或资源加载失败时触发。abort
事件在用户取消加载时触发。
二、session历史事件
pageshow 事件,pagehide 事件
默认情况下,浏览器会在当前会话(session)缓存页面,当用户点击“前进/后退”按钮时,浏览器就会从缓存中加载页面。
pageshow
事件在页面加载时触发,包括第一次加载和从缓存加载两种情况。如果要指定页面每次加载(不管是不是从浏览器缓存)时都运行的代码,可以放在这个事件的监听函数。 pageshow
事件有一个persisted
属性,返回一个布尔值。页面第一次加载时,这个属性是false
;当页面从缓存加载时,这个属性是true
。
pagehide
事件与pageshow
事件类似,当用户通过“前进/后退”按钮,离开当前页面时触发。它与 unload
事件的区别在于,如果在 window
对象上定义unload
事件的监听函数之后,页面不会保存在缓存中,而使用pagehide
事件,页面会保存在缓存中。pagehide
事件实例也有一个persisted
属性,将这个属性设为true
,就表示页面要保存在缓存中;设为false
,表示网页不保存在缓存中,这时如果设置了unload
事件的监听函数,该函数将在 pagehide
事件后立即运行。
popstate 事件
popstate
事件在浏览器的history对象的当前记录发生显式切换时触发。注意,调用history.pushState()
或history.replaceState()
,并不会触发popstate
事件。该事件只在用户在history
记录之间显式切换时触发,比如鼠标点击“后退/前进”按钮,或者在脚本中调用history.back()
、history.forward()
、history.go()
时触发。
hashchange 事件
事件在 URL 的 hash 部分(即#
号后面的部分,包括#
号)发生变化时触发。该事件一般在window
对象上监听。
hashchange
的事件实例具有两个特有属性:oldURL
属性和newURL
属性,分别表示变化前后的完整 URL
。
三、网页状态事件
DOMContentLoaded事件
网页下载并解析完成以后,浏览器就会在document对象上触发 DOMContentLoaded 事件。
readystatechange事件
当 Document 对象和 XMLHttpRequest 对象的readyState
属性发生变化时触发。document.readyState
有三个可能的值:loading
(网页正在加载)、interactive
(网页已经解析完成,但是外部资源仍然处在加载状态)和complete
(网页和所有外部资源已经结束加载,load
事件即将触发)。
四、窗口事件
scroll事件
在文档或文档元素滚动时触发,主要出现在用户拖动滚动条。
resize事件
在改变浏览器窗口大小时触发,主要发生在window对象上面。
fullscreenchange事件,fullscreenerror事件
fullscreenchange
事件在进入或推出全屏状态时触发,该事件发生在document
对象上面。
fullscreenerror
事件在浏览器无法切换到全屏状态时触发。
五、剪切板事件
cut
:将选中的内容从文档中移除,加入剪切板时触发copy
:进行复制动作时触发paste
:剪切板内容粘贴到文档后触发
六、焦点事件
- focus:元素节点获得焦点后触发,该事件不会冒泡。
- blur:元素节点失去焦点后触发,该事件不会冒泡。
- focusin:元素节点将要获得焦点时触发,发生在focus事件之前。该事件会冒泡。
- focusout:元素节点将要失去焦点时触发,发生在blur事件之前。该事件会冒泡。
这四个事件都继承了FocusEvent接口。FocusEvent实例具有以下属性。
- FocusEvent.target:事件的目标节点。
- FocusEvent.relatedTarget:对于focusin事件,返回失去焦点的节点;对于focusout事件,返回将要接受焦点的节点;对于focus和blur事件,返回null。
由于focus和blur事件不会冒泡,只能在捕获阶段触发,所以addEventListener方法的第三个参数需要设为true。