用键盘想文本框中文本框输入字符长度,什么事件会被触发

监听键盘的输入事件[转]
监听键盘的输入事件[转]
发布时间: 19:10:48
编辑:www.fx114.net
本篇文章主要介绍了"监听键盘的输入事件[转] ",主要涉及到监听键盘的输入事件[转] 方面的内容,对于监听键盘的输入事件[转] 感兴趣的同学可以参考一下。
来自:进行web开发时,我们会对表单做提交验证,为了进一步增强用户体验,要在用户输入时就进行限制,比如针对电话只能输入数字、长度不允许超过固定值等。随着微博的流行,从Twitter开始,很多记录的文字输入在设计时就都添加上了字数限制与提示的功能,这已成了输入框的标配。本文从这一需求出发,说明Javascript中键盘事件和输入控制的技术细节。功能需求限制输入功能一般满足下面的需求:统计还可以输入多少文字并实时显示限制的字数可能是以汉字为单位计数,这时要判断单字节、双字节的输入可能还要求达到限制数量后,输入框不可输入,或仅允许输入固定类型(如果用keyup事件,输入框内容会跳动)这里讨论实现这些需求的方案,基于我们日常使用的标准键盘和最常见的四种内核的浏览器,对于一个web应用,这些兼容就足够了。下面讨论中仅以事件名称代替,不加前缀‘on’解决方案为了实时监控文字的多少,需要对每个输入进行监控,每次改变都应该被纳入到监控中。Javascript中的键盘事件只是监控每次按键,但是对于右键粘贴、拖拽方式改变输入框的内容就无能为力了,我们只能去探寻其他事件。对字数和类型的限制,原理上都是检查输入的是否符合要求,不符合就把不允许的部分删除,重新给输入框赋值。但是只要用过键盘事件就会发现,keydown、keypress 事件无法获取刚输入的内容,而 keyup 又貌似控制晚了:总是看到字符被输入又再被删除。什么事件能够满足这种需求呢?那就是 input 和 propertychange 事件。如果你知道这两个事件,一切都不是问题,只要监控它们,既能得到新输入的内容,又能随时控制内容,而不担心文字显示又删除的过程展示在用户面前。$('textarea').bind('input', function () {
var value = $(this).val();
// todo: 处理截断 or 对比是否超出限制 }); 但我还是想看看用键盘事件能够做到哪一步。/* 因为中文不同浏览器返回不同,这里只考虑键盘上字符的输入 */ var input = $('textarea'),
limitLength = 20, // 限制字符长度
markForCountWhenKeyup = false; // 标记需要keyup后才能计数(限制输入时控制删除键)
// 绑定事件 input.bind('keydown', keydown)
.bind('keyup', keyup);
// keydown事件 function keydown (evt) {
// 键盘上的全部可打印键
var isPrintableKey = function (k) {
return !(evt.altKey || evt.ctrlKey || evt.metaKey) && (
k === 32 ||
(k &= 48 && k &= 57) ||
(k &= 65 && k &= 90) ||
(k &= 96 && k &= 105) || // 小键盘数字
// 其他符号键
(k === 106 || (k &= 186 && k &= 192) || (k &= 219 || k &= 222))
switch (evt.keyCode) {
// 1. 回车键,除了shift+Enter执行默认换行,其他Enter都是提交
if (!evt.shiftKey) {
// todo: 提交处理
evt.preventDefault(); // 防止换行
// 2. 删除键/中文,在keyup后再计算字数
// backspace
markForCountWhenKeyup = true;
// 3. 输入键,在原内容基础上加1 (这时文本框的值还未改变)
if (isPrintableKey(evt.keyCode)) {
// 超出范围,不再允许将该次键值输入
if (input.val().length + 1 - limitLength & 0) {
evt.preventDefault();
} } // 配合keydown,只有退格、删除键才响应,检测字数。(这时文本框的值已经改变) function keyup (evt) {
var k = evt.keyCode;
if (markForCountWhenKeyup && (k === 8 || k === 46 )) {
// 允许删除
markForCountWhenKeyup = false;
} } 上面的代码满足键盘输入控制,但是仅能处理键盘上看得到的字符的输入,一旦遇到中文、粘贴、拖拽改变输入框内容时,就无能为力了。技术探究输入元素HTML中一般用到的输入文字的元素是文本框,包括input、textarea。富文本编辑不在讨论之列。js中的键盘事件js中的键盘事件只有三种:keydown、keyup、keypress。它们触发的顺序是:keydown -& keypress -& keyup。当按下一个键不放开,一般会重复地触发 keydown+keypress,直到放开后触发一个 keyup 事件。三种键盘事件区别keydown 和 keyup 是比较底层的事件,分别对应一个键的按下与放开,键盘上任何一个键被点按,都会触发这两个事件。keypress 更接近用户,只有可打印的字符和控制字符(如换行)被键入才触发。keydown 和 keyup 被触发后,都会产生一个虚拟键盘码,用来表示按下的是哪个键。键盘上的每个键只对应一个虚拟键盘码。keypress 被触发后产生的是实际键入的字符的 Ascll 编码,而没有对应的虚拟键盘码。这两种编码有时在数值上是相等的。如何访问到事件产生的编码信息,就又要涉及到浏览器兼容问题,几大浏览器处理是不同的。获取按键信息在 IE 中,事件对象在&window.event&中,编码信息放到了&keyCode&属性内。keyCode属性的含义根据事件变化,在 keydown 和 keyup 事件中表示的是虚拟键盘码,在 keypress 时表示的就是实际字符的编码。非IE浏览器内,事件对象在回调函数中返回,存储在事件对象的keyCode、which、charCode&中,看到了吧,相比 IE 中增加了两个属性。keyCode&只表示虚拟字符编码,因为 keypress 事件没有该编码,在这个事件里,keyCode的值是 0。charCode&只在 keypress 事件中有值,为实际键入的字符编码,其他事件中都是 0。which&更像是 IE 中的&keyCode,当 keydown 和 keyup 事件中有虚拟键盘码时,which&表示虚拟键盘码;当 keypress 事件中只有字符编码时,which&又表示字符编码。上面是 firefox 浏览器的标准表现形式。webkit 内核浏览器中(safari、chrome),相比 firefox,在 keypress 时,keyCode&不再是 0,而是和&which、charCode&两个属性的值相等。opera 浏览器相比 webkit 内核的浏览器,三个 key 事件都去掉了&charCode&属性。当按下小写字母a键时,对应关系如下:
charCode --ie6/7/8:------------------------------
undefined keypress
undefined keyup
undefined --ie9/10:------------------------------ keydown
0 keypress
0 --firefox:------------------------------ keydown
0 keypress
0 --webkit:------------------------------- keydown
0 keypress
0 --opera:-------------------------------- keydown
0 keypress
0 除了老版的 IE、firefox,其他浏览器的表现是一致的&jQuery 为 IE 事件增加了 which 属性值因此,如果只是 keydown 和 keyup 事件,都访问事件对象的&keyCode&即可;如果是 keypress 事件,就要区别对待了,IE 中还是使用&keyCode,非 IE 要使用&which&,这时他们表示的是实际输入的字符码,通过&String.fromCharCode()&获得实际的可打印字符。组合按键除了单个按键,还有组合按键,如很多快捷键是由功能键和其他键组合而来。这些按键除了 opera,都比较一致:ctrlKey&--- Ctrl 键shiftKey--- Shift 键altKey&---- Alt 键metaKey&--- command 键(Mac下)中文支持情况各个浏览器对中文的支持不同,中文输入法下,不同浏览器下按键触发的键盘码是不同的。但它们都不产生 keypress 事件。webkit 内核浏览器:每按一个键都产生 keydown、keyup;keydown 时,可打印字符的键盘码都是 229;keyup 时返回正常的键盘码值。firefox 浏览器:输入中文的中间过程中不产生任何键盘事件;开始输入的第一个按键产生正常的 keydown,结束的 空格或回车 产生 keyup,键盘码是正常的键盘码。opera 浏览器:Window 系统下与 webkit 表现一致;Mac下每次按键都只产生 keydown 事件,键盘码是正常键盘码。ie 浏览器:6~10几个版本触发方式与键盘码值与 webkit 内核浏览器一致。总之,多数浏览器中文输入法(搜狗输入法)一般开始都是299,但是有些会因系统有差异。用键盘事件控制中文输入不太靠谱。输入框内容改变事件form 表单中很多元素都有 change 事件,当表单元素的值发生变化时,就会触发该事件。只能是由用户触发的改变才会发出 change 事件,用脚本修改值是不会产生的,form的很多事件都是如此,包含本文提到的。但是在输入框中,需要焦点离开,改变的状态才会触发这一事件,也就是输入时每次的改变我们是无法知道的,只有在输入框外点击一下,如果内容变化了,才会发出 change 事件。幸运的是,还有一个 input 事件,会在每次输入框的内容改变时触发,无论是敲键盘输入,还是粘贴文本,甚至是拖拽,只要内容值变化了,就会触发该事件。这个事件是 HTML5 的标准事件,除了老版 IE 基本都支持,它一般藏的比较深,很少会看到关于它的介绍。在 Chrome console 中的自动提示中可以看到一个长长的事件列表,说不准哪些将来我们就会用到了。&Chrome console 中提示的 textarea 支持的事件针对不支持的老版 IE6/7/8,还有一个替代事件:propertychange。看它的名字就知道它监视的是属性值的改变,而输入值&value&只是一个元素众多属性中的一个,因此这个事件返回对象需要过滤出我们需要的属性&value。有一点要特别注意的是,IE9/10 同时支持 input 和 propertychange,如果两种事件都注册了,就都会触发,可能会被重复处理。事件触发顺序当我们把键盘事件和内容改变事件放到一起,他们触发的顺序是: keydown -& keypress -& input/propertychange -& keyup。我们按可打印的键,它表示的字符是什么时候输入到文本框中的呢?根据测试观察,文本框中的值在 keypress 事件中还没有改变,但在 input 中已经改变了。在 input 中改变输入框的值,看上去没有任何不妥;如果放到 keyup 事件中再去改变,能看到文字敲进去了然后又被改变了,跳动很明显。在 input 的时候,文本框的值已经改变,但是尚未渲染显示出来,这时用脚本改变文本框中的值,不会出现内容跳动情况。如果在 input 的事件处理函数中设置断点,就能看到内容已经改变,所以我们在这里面获取到的值是改变后的值,只是没有呈现出来。没有看源码与文档,仅从现象推理,希望看到相关资料的能不吝分享。结语要实时监控输入框内容变化,用 input(propertychange) 会简单有效。keydown、keyup 这两个键盘事件可以直接用&event.keyCode&取得键盘码值,keypress 要得到实际的字符码,需要&event.keyCode || event.which,然后可以用String.fromCharCode()&获取实际的字符表示。最后,各个类型的浏览器及其不同版本可能会有些差别 :( 。中文的输入,测试中发现不同系统、不同版本都会有影响,无法用键盘事件来控制。
一、不得利用本站危害国家安全、泄露国家秘密,不得侵犯国家社会集体的和公民的合法权益,不得利用本站制作、复制和传播不法有害信息!
二、互相尊重,对自己的言论和行为负责。
本文标题:
本页链接:事件流IE和Netscape开发团队提出了完全相反的两种事件流的概念,事件冒泡流和事件捕获流。事件冒泡事件由最具体的元素开始,逐级向上传播到较不具体的元素,最终到文档。事件捕获事件捕获从document开始,逐级向下,最后传到最具体的节点。DOM事件流DOM2级事件定义的事件流包含3个阶段:事件捕获阶段,处于目标阶段,事件冒泡阶段。 捕获阶段会从文档节点自上而下传递直到目标节点的上一个节点;处于目标阶段时传到目标节点,冒泡阶段开始向上传递知道文档节点。 规定是捕获阶段事件不传递到目标节点,但是大多数浏览器就传递到了,这就意味着有2次机会在目标对象上操作事件。事件处理程序响应某个事件的函数HTML事件处理程序可以使用HTML特性来指定。&input type="button" value="Click Me" onclick="alert(event.type)"&&input type="button" value="Click Me" onclick="alert(this.value)"&&input type="button" value="hahaah" onclick="clickButton(this)"&function clickButton(element) {
alert(element.value);}这里注意JS代码中如果出现&”“&&要使用转义字符。 这样写事件处理程序是很不灵活的,HTML代码和JS代码耦合度太高。 不过这样写是有一些方便的地方的,这样写的JS语句会被包含在一个动态创建的函数中,这个函数中会存在一个局部变量event事件对象,而且通过this这个变量可以访问到元素本身。这个函数还会使用with拓展作用域,让你更方便的直接访问document及元素本身的成员:function(){
with(document){
with(this){
//你的代码
}}//于是可以直接这样写&input type="button" value="Click Me" onclick="alert(value)"&如果要调用函数,这个函数在JS中要处于全局作用域哦,而且要使用this对象要将this作为参数传进去,否则是访问不到的。 这样写事件处理程序是有问题的,一个是紧耦合的问题,一个是时间差,如果你的JS文件是放在最下面的,有可能会出现函数已经绑在事件上了可是JS却还没给出函数定义,这样就会报错,为了避免这样的情况出现,我们使用try-catch:&input type="button" value="Click Me" onclick="try{clickButton(this);}catch(ex){}"&不过还是不那么理想是吧。DOM0级事件处理程序每个元素都有自己的事件处理程序属性,以这种方式添加的事件会在事件流的冒泡阶段被处理。传入的处理函数是在元素的作用域中运行。将这个属性指向空就取消了事件绑定,值得一提的是,如果你使用上面的HTML特性指定事件处理函数,这个属性里就包含着HTML里你写的事件函数的代码,置空也同样可以取消绑定。var btn = document.getElementById("myBtn");btn.onclick = function(){
alert(this.id);
//"myBtn"};btn.onclick = null;DOM2级事件处理程序IE8及以下不支持DOM2级事件 DOM2级事件定义了两种方法:addEventListener()
removeEventListener()。这两个方法接受3个参数,要处理的事件名,处理函数,和一个布尔值。这个布尔值代表在捕获节点调用事件处理程序(true)还是在冒泡过程中调用。 这样添加意味着可以添加多个事件处理程序,在事件触发时会按照添加的顺序来执行。传入的处理函数是在元素的作用域中运行。 注销时要传入完全相同的函数才能注销,这就意味着如果你的处理函数是以匿名函数的方式传递进去的,那就不可能注销了哦,因为再传进去一个匿名函数也不是原先那个了:var btn = document.getElementById("myButton");var body = document.//冒泡阶段body.addEventListener("click", function(){
alert("Hello world!");}, false);//捕获阶段body.addEventListener("click", function(){
alert("Hello world!");}, true);//如果是使用匿名函数注册的btn.addEventListener("click", function(){
alert(this.id + "匿名");}, false);//注销不掉btn.removeEventListener("click", function(){
alert(this.id);}, false);//这样就能注销掉了var handler = function(){
alert(this.id + "非匿名");};btn.addEventListener("click", handler, false);btn.removeEventListener("click", handler, false);IE事件处理程序IE8及以下不支持DOM2级事件,但是支持两个类似方法attachEvent()、detachEvent() 只支持冒泡阶段 传入的处理函数是在全局作用域中运行 添加多个事件时触发顺序与添加顺序相反 注销时同样需要传入相同的参数,匿名函数无法注销。var btn = document.getElementById("myBtn");btn.attachEvent("onclick", function(){
alert(this === window); //true});var handler = function(){
alert("Clicked");};btn.attachEvent("onclick", handler);btn.detachEvent("onclick", handler);跨浏览器事件处理程序优先使用DOM2级的,再不行使用IE专有的,最后使用DOM0级的(一般不可能用到)var EventUtil = {
addHandler: function(element, type, handler){
if (element.addEventListener){
element.addEventListener(type, handler, false);
} else if (element.attachEvent){
element.attachEvent("on" + type, handler);
element["on" + type] =
removeHandler: function(element, type, handler){
if (element.removeEventListener){
element.removeEventListener(type, handler, false);
} else if (element.detachEvent){
element.detachEvent("on" + type, handler);
element["on" + type] = null;
} }};var btn = document.getElementById("myButton");var handler = function(){
alert("Clicked");};EventUtil.addHandler(btn, "click", handler);EventUtil.removeHandler(btn, "click", handler);事件对象事件被触发时会产生一个事件对象,这个对象中包含着所有与事件有关的信息,包括导致事件的元素,事件的类型以及其他各个事件特定的信息。所有浏览器都支持event对象,但是实现不同。DOM中的事件对象兼容DOM的浏览器会将一个event对像传入到事件处理程序中,三种方式都有btn.onclick = function(event){
alert(event.type); //"click"};btn.addEventListener("click", function(event){
alert(event.type); //"click" }, false);&input type="button" value="Click Me" onclick="alert(event.type)"/&所有的event对象都会有下面的方法:
事件是否冒泡
cancelable
是否可以取消事件的默认行为
currentTarget
当前正在处理事件的那个元素
defaultPrevented
是否已经调用了preventDefault()。DOM3
与事件相关的细节信息
eventPhase
触发事件的阶段,1捕获,2处于目标,3冒泡
preventDefault()
取消事件的默认行为
stopImmediatePropagation()
取消进一步的捕获或冒泡,同时阻止任何事件处理程序被调用。DOM3
stopPropagation()
取消进一步的捕获或冒泡
事件的目标
true表示是由浏览器生成的事件,false说明是JS创建的。DOM3
事件的类型
AbstractView
与事件关联的抽象视图,等同于发生事件的window对象关于currentTarget的解释 在事件处理程序的内部,this始终指向currentTarget的值,而target则只包含事件的实际目标。//当事件处理函数就在按钮上时可能看不出什么区别,但是当在按钮的父元素上时就不同了document.body.onclick = function(event){
alert(event.currentTarget === document.body); //true
alert(this === document.body); //true
alert(event.target === document.getElementById("myBtn")); //true };preventDefault() 比如a标签的默认行为就是跳转到URL,使用event.preventDefault()可以阻止。 cancelable是true的事件才可以阻止。var link = document.getElementById("myLink");link.onclick = function(event){
event.preventDefault();};IE中的事件对象event在IE中是window的一个属性,可以直接获取var btn = document.getElementById("myBtn");btn.onclick = function(){
var event = window.
alert(event.type);
//"click"};btn.attachEvent("onclick", function(event){
alert(event.type); //"click"});
cancelBubble
默认为false,将其设置为true就可以取消冒泡
returnValue
默认为true,设为false可以取消事件的默认行为
srcElement
与target相同
事件的类型要注意在IE中的事件处理程序最好不要使用this,使用event.srcElement比较保险btn.attachEvent("onclick", function(event){
alert(event.srcElement === this); //false});跨浏览器的事件对象根据浏览器之间的区别,在刚才的EventUtil中添加下列方法:getEvent: function(event){
return event ? event : window.event;},getTarget: function(event){
return event.target || event.srcE},preventDefault: function(event){
if (event.preventDefault){
event.preventDefault();
event.returnValue = false;
}},stopPropagation: function(event){
if (event.stopPropagation){
event.stopPropagation();
event.cancelBubble = true;
} }这样使用~~var link = document.getElementById("link");var body = document.var handler = function (event) {
event = EventUtil.getEvent(event);
var target = EventUtil.getTarget(event);
EventUtil.preventDefault(event);
EventUtil.stopPropagation(event);
alert(target);
alert(event.target);}link.addEventListener("click", handler, false);body.addEventListener("click", handler, false);事件类型DOM3级事件规定了如下几类事件:UI事件焦点事件鼠标事件滚轮事件文本事件键盘事件合成事件变动事件除了这几类事件,HTML5也定义了一组事件,有的浏览器还有一些专有事件。UI事件DOMActivate:表示元素已经被用户操作,DOM3已经弃用了load:当页面完全加载后在window上触发,当所有框架加载完毕时在框架集上触发,图像加载完时在img上触发,当嵌入内容加载完毕时在object元素上触发unload:load对应的那些,完全卸载后触发abort:在用户下载过程中,如果内容没下载完,在object元素上触发error:JavaScript出错时在window上触发,无法加载图片时在omg上触发,有一个或多个框架无法加载时在框架集上触发select:用户选择文本(input,texture)中的一个或多个字符时触发resize:当窗口或框架大小改变时在window或框架触发scroll:当用户滚动带滚动条的元素时在该元素上触发,body元素有页面的滚动条要确定浏览器是否支持:var isSupported = document.implementation.hasFeature("HTMLEvents", "2.0");var isSupported = document.implementation.hasFeature("UIEvent", "3.0");load事件 DOM2级事件规范是在document上触发load事件,不过为了兼容所有浏览器都在window上实现了loadEventUtil.addHandler(window, "load", function(){
var image = document.createElement("img");
EventUtil.addHandler(image, "load", function(event){
event = EventUtil.getEvent(event);
alert(EventUtil.getTarget(event).src);
//就算不吧img添加到文档,只要设置了SRC就会开始下载
//document.body.appendChild(image);
image.src = "/images/icon_01.png";});有的浏览器在script和link上也会有load事件unload事件 这个事件在文档在完全被卸载后触发,只要用户从一个页面切换到另一个页面就回触发这个事件。利用这个事件可以清除引用EventUtil.addHandler(window, "unload", function(event){
alert("Unloaded");});resize事件EventUtil.addHandler(window, "resize", function(event){
alert("Resized");});浏览器可能会在窗口大小改变1px的时候就触发这个事件,要小心不要在这里放开销大的方法。 scroll事件 这个事件可以添加到任何有滚动条的元素上。也是会被重复触发的。页面的EventUtil.addHandler(document.getElementById("scrollTest"), "scroll", function(event){
alert("div Scrolled");});EventUtil.addHandler(window, "scroll", function(event){
alert("window Scrolled");});焦点事件与document.hasFocus()和document.activeElement配合可以知晓用户在页面上的行踪。blur:在元素失去焦点时触发,不会冒泡DOMFocusIn:元素获得焦点时触发,冒泡,DOM3废弃DOMFocusOut:元素失去焦点,DOM3废弃focus:元素获得焦点时触发,不冒泡focusin:与focus等价,但冒泡,不是所有浏览器都支持,较新的都支持focusout:失去焦点,冒泡,较新的支持当焦点从一个元素移到另一个,依次触发下面的事件:focusoutfocusinblur
DOMFocusOut
DOMFocusIn focusin和focus还是有一些区别的,试试这两个你就知道啦:&input type="text" id="textField"&var btn = document.getElementById("textField");btn.addEventListener("focus",function () {
alert("button On Focus");},false);btn.addEventListener("focusin",function () {
alert("button On Focus");},false);focus事件会在alert被关掉之后,焦点回到input时再次触发,alert会不停的出现。 focusing就只会alert一次。鼠标与滚轮事件DOM3级事件中定义了9个鼠标事件:click:单击主鼠标按钮或按下回车键时触发dblclick:双击主鼠标按钮mousedown:用户按下任意鼠标按钮mouseup:释放鼠标按钮时触发mouseenter:光标从元素外首次移到元素内触发。不冒泡。而且在光标移动到后代元素上时不会触发。mouseleave:移出元素时触发,不冒泡,移出后代元素时不会触发。mousemove:在元素内部移动时重复触发mouseout:指针位于一个元素上方,移入另一个元素时触发,移入的元素是当前元素的子元素时也会触发mouseover:移入本元素时触发,移入本元素的某个子元素时也会触发mousewheel:跟踪鼠标滚轮或触控板滚动其中click事件的触发依赖在同一个元素上相继触发mousedown,mouse。dblclick则要在同一个元素上触发两次click。 客户区坐标位置 位置信息保存在clientX,clientY。表示鼠标事件发生时鼠标指针在视口中的位置。要注意的是,这个是指针相对于视口的位置,如果你的页面发生滚动而鼠标没动,这个坐标不会有变化。var div = document.getElementById("myDiv");EventUtil.addHandler(div, "click", function(event){
event = EventUtil.getEvent(event);
alert(event.clientX + "," + event.clientY);});页面坐标位置 这个就真的是在页面中的位置了pageX,pageYvar div = document.getElementById("myDiv");EventUtil.addHandler(div, "click", function(event){
event = EventUtil.getEvent(event);
alert("Page coordinates: " + event.pageX + "," + event.pageY);});屏幕坐标位置 鼠标相对屏幕的坐标信息screenX,screenY 修改键 在鼠标按下的时候可以检查Shift、Ctrl、Alt、Meta哪个键被按下了。由此做一些特定的操作。由event的4个属性来检查:shiftKey、ctrlKey、altKey、metaKey。var div = document.getElementById("myDiv");EventUtil.addHandler(div, "click", function(event){
event = EventUtil.getEvent(event);
var keys = new Array();
if (event.shiftKey){
keys.push("shift");
if (event.ctrlKey){
keys.push("ctrl");
if (event.altKey){
keys.push("alt");
if (event.metaKey){
keys.push("meta");
alert("Keys: " + keys.join(","));});相关元素 mouseover、mouserout这两个事件是有相关元素的。比如mouseover时你移出的那个元素就是相关元素。可以通过event的relatedTarget属性来获得。IE8及以下通过fromElement和toElement来获得。由于又有兼容问题,再次拓展我们的工具包咯:getRelatedTarget: function(event){
if (event.relatedTarget){
return event.relatedT
} else if (event.toElement){
return event.toE
} else if (event.fromElement){
return event.fromE
return null;
}}鼠标按钮 click只在鼠标主键被按下时触发,所以并不存在检测按钮的问题,不过对于mousedown和mouseup来说就不一样了,在他们的event中有一个button属性。DOM的button属性有如下3个值:0主键,1滚轮键,2次键。 IE8之前也有button,不过差别比较大,有8个值:0:没有按钮1:主2:次3:主次同时4:滚轮5:主,滚轮同时6:次,滚轮同时7:3个同时是时候拓展工具包了:getButton: function(event){
if (document.implementation.hasFeature("MouseEvents", "2.0")){
return event.button;
switch(event.button){
}}mousewheel事件 在滚轮滚动时触发,event有一个特殊的属性wheelDelta向上滚是负值,向下滚是正值。Opera早期版本相反。EventUtil.addHandler(document, "mousewheel", function(event){
event = EventUtil.getEvent(event);
var delta = (client.engine.opera && client.engine.opera & 9.5 ?
-event.wheelDelta : event.wheelDelta);
alert(delta);});除firefox外都支持这个事件,firefox支持的是DOMMouseScroll。EventUtil.addHandler(window, "DOMMouseScroll", function(event){
event = EventUtil.getEvent(event);
alert(event.detail);});触摸设备 触摸设备不支持dblclick事件,双击会放大页面 轻击可单击的元素会触发mousemove事件。如果此操作会导致内容变化,将不再有其他事件发生;如果屏幕没有因此发生变化,那么会依次发生mousedown、mouseup、click事件 轻击不可单击的元素不会触发任何事件。 可单击元素是指那些单击有默认操作的元素,或者你指定了onclick事件处理函数的元素。 mousemove事件也会触发mouseover和mouseout事件。 两个手指放在屏幕上且页面随手指移动而滚动时会触发mousewheel和scroll事件。 无障碍性问题 无障碍主要就是针对盲人的设计,盲人会使用屏幕阅读器,而屏幕阅读器使用键盘来触发事件。 所以尽量使用click事件,因为回车可以直接触发。 如果一定要使用那些键盘默认触发不了的操作,比如onmouseover、dblclick,应添加键盘快捷方式。键盘与文本事件键盘事件:keydown:当用户按下任意键触发,按住不放重复触发 keypress:当用户按下键盘上字符键时触发,按住不放时重复触发keyup:当用户释放键盘上的键时触发文本事件:textInput:文本插入文本框前会触发在用户按下字符键时会触发keydown,紧接着keypress,如果是在文本框里输入文字这时会触发textInput,如果用户抬起来了按键就会触发keyup,不抬起来会重复触发keydown,keypress,textInput。 键盘事件也支持shiftKey、ctrlKey、altKey、metaKey。 键码
在发生keydown和keyup事件时,event对象的keyCode属性中会包含一个代码,数字字母键就是ASCII码。 字符编码 发生keypress意味着按下的键会影响到屏幕中文本的显示,按下能插入或删除字符的键都会触发keypress事件。 属性charCode只有在keypress事件时才包含值,这个值是按下的那个键所带代表字符的ASCII码,而此时的keyCode可能等于0,也可能等于键码,所以跨浏览器要小心:getCharCode: function(event){
if (typeof event.charCode == "number"){
return event.charC
return event.keyC
}}EventUtil.addHandler(textbox, "keypress", function(event) {
event = EventUtil.getEvent(event);
alert(String.fromCharCode(EventUtil.getCharCode(event)));});DOM3级变化 DOM3中不再包含charCode,改为key和char。key就是键名字符串:“K”、“g”、“Shift”等。char在字符键情况下与key相同,非字符键时为null。 textInput事件 只有可编辑区域才会触发textInput。且只有有效的输入会触发。这个事件的事件对象里有个data,这个属性里保存的就是实实在在的输入数据,你输入a或A或粘贴进来的asdfasdf在这里都会得到体现。var textbox = document.getElementById("myText");EventUtil.addHandler(textbox, "textInput", function(event){
event = EventUtil.getEvent(event);
alert(event.data);});还有一个属性叫inputMethod,表示把文本输入到文本框的方式,粘贴,拖放,手写之类的,只有IE实现了。复合事件只有IE9+支持 DOM3级中新添加的事件用来处理IME的输入序列,IME是输入法编辑器,可以让用户输入在物理键盘上找不到的字符,IME通常需要按住多个键最终只输入一个字符。有3个事件:compositionstart:IME被打开,这是event里的data属性是正在编辑的文本(比如已经被选中马上要被替换的文本,正常输入情况下一般是空)compositionupdate:在向输入字段插入新字符时触发,data包含正插入的新字符compositionend:IME关闭,返回正常键盘输入状态时,data包含此次插入的所有字符。EventUtil.addHandler(textbox, "compositionstart", function(event){
event = EventUtil.getEvent(event);
alert(event.data);});变动事件DOM2级的变动事件在DOM中某一部分发生变化时给出提示,跟少用到DOMSubtreeModifiedDOMNodeInsertedDOMNodeRemoved
DOMNodeInsertedIntoDocument
DOMNodeInserted
DOMNodeRemovedFromDocument
DOMNodeRemoved
DOMAttrModified
DOMCharacterDataModified
HTML5事件contextmenu事件
这个事件在右键调出上下文菜单时被触发,可以通过取消默认事件来弹出自己的右键菜单,这个事件冒泡。EventUtil.addHandler(document, "contextmenu", function(event){
event = EventUtil.getEvent(event);
EventUtil.preventDefault(event);
var menu = document.getElementById("myMenu");
menu.style.left = event.pageX + "px";
menu.style.top = event.pageY + "px";
menu.style.visibility = "visible";});beforeunload事件 这是为了让开发人员在页面被卸载前有可能提醒用户EventUtil.addHandler(window, "beforeunload", function(event){
event = EventUtil.getEvent(event);
var message = "I'm really going to miss you if you go.";
event.returnValue =
return});DOMContentLoaded事件 这个事件和window的load事件不同,这个不理会各种图片,JS等文件是否加载完成,只要完整的DOM结构OK了就触发。 这允许我们尽早的添加事件处理程序和DOM操作等。 这个事件的目标实际上是document,虽然会冒泡到windowsEventUtil.addHandler(document, "DOMContentLoaded", function(event){
alert("Content loaded");
alert(event.target);//[object HTMLDocument]});readystatechange事件 IE、Firfox 4+、Opera。 为某些元素提供的事件,目的是提供与文档或元素的加载状态有关的信息,支持这个事件的每个对象都有一个readyState属性,有5个可能值:uninitialized、loading、loaded、interactive、complete interactive,complete不一定哪个先出现,所以要快的话两个一起检测,为避免执行两次,检测到了就注销事件EventUtil.addHandler(document, "readystatechange", function(event){
event = EventUtil.getEvent(event);
var target = EventUtil.getTarget(event);
if (target.readyState == "loaded" || target.readyState == "complete"){
EventUtil.removeHandler(target, "readystatechange", arguments. callee);
alert("Content Loaded");
}});pageshow和pagehide 有的浏览器有一种特性叫往返缓存,使用户在使用前进后退按钮时更快,这个缓存完全保存了整个页面,包括JS的执行状态,这就意味着不会再触发load事件。 pageshow无论这个页面是新打开的还是在往返缓存中的,都会在这个页面显示的时候触发。新打开的会在load后触发。 其event对象中有一个persisted属性,是true时代表是从往返缓存中恢复的。(function(){
var showCount = 0;
EventUtil.addHandler(window, "load", function(){
alert("Load fired");
EventUtil.addHandler(window, "pageshow", function(){
showCount++;
alert("Show has been fired " + showCount +
" times. Persisted? " + event.persisted);
});})();pagehide是在unload之前被触发的。 指定了onunload事件的页面不会被存在往返缓存中,因为onunload事件一般是为了撤销在load事件中做的事。 hashchange事件 这个事件在URL参数列表发生改变时触发,这个事件要添加到window对象EventUtil.addHandler(window, "hashchange", function(event){
alert("Current hash: " + location.hash);});设备事件这些事件是针对移动设备的 orientationchange事件 这是Apple在移动版本的Safari中加入的事件,其window.orientation中可能包含3个值:0、90、-90。只要用户改变了设备的查看模式就会触发该事件。iOS设备都支持这个事件。EventUtil.addHandler(window, "orientationchange", function(event){
alert(window.orientation);});MozOrientation事件 这是火狐引入的检测设备旋转的事件,其event中有x、y、z三个值,有加速计的设备就可以用EventUtil.addHandler(window, "MozOrientation", function(event){
var output = document.getElementById("output");
output.innerHTML = "X=" + event.x + ", Y=" + event.y + ", Z=" + event.z +"&br&";});deviceorientation事件 这个事件也是检测加速计来获得设备方向的变化,变化时在window上触发。设备在平躺时z轴向上。 事件的event对象中有如下5个属性:alpha:围绕z轴旋转时,y轴的度数差,0~360的浮点数beta:围绕x轴旋转时,z轴的度数差-180~180的浮点数gamma:围绕y轴旋转时,z轴的度数差,-90~90的浮点数absolute:布尔值,设备是否返回一个绝对值compassCalibrated:布尔值,指南针是否校准EventUtil.addHandler(window, "deviceorientation", function(event){
alert("Alpha=" + event.alpha + ", Beta=" + event.beta + ", Gamma=" + event.gamma);});devicemotion事件 这个事件告诉开发人员设备什么时候移动,其事件对象包含以下属性:acceleration:一个包含xyz的对象,排除重力每个方向的加速度accelerationIncludingGravity:考虑重力,每个方向的加速度interval:以毫秒表示的时间值,在每次事件中是常量。rotationRate:包含表示方向的alpha、beta、gamma属性的对象以上这些值读不到就是null,用前先检测EventUtil.addHandler(window, "devicemotion", function(event){
var output = document.getElementById("output");
if (event.rotationRate !== null){
output.innerHTML += "Alpha=" + event.rotationRate.alpha + ", Beta=" +
event.rotationRate.beta + ", Gamma=" +
event.rotationRate.gamma;
}});触摸与手势事件触摸事件 在iOS和Android上实现了touchstart:每根手指触摸屏幕时触发touchmove:手指在屏幕上滑动时连续触发,调用preventDefault()可以阻止页面滚动touchend:手指移开touchcancel:系统停止跟踪触摸时触发 上面几个事件都会冒泡,也都可以取消。 event对象中常见的鼠标事件的属性都有:bubbles、cancelable、view、clientX、clientY、screenX、screenY、detail、altKey、shiftKey、ctrlKey、metaKey。 还包含三个用于跟踪触摸事件的属性:touches:表示当前跟踪的触摸操作的Touch对象的数组targetTouchs:特定于事件目标的Touch对象的数组changeTouches:表示自上次触摸以来发生什么改变的Touch对象的数组每个Touch对象有下列属性:clientXclientYidentifier:表示触摸的唯一IDpageXpageYscreenXscreenYtarget
function handleTouchEvent(event){
if (event.touches.length == 1){
var output = document.getElementById("output");
switch(event.type){
case "touchstart":
output.innerHTML = "Touch started (" +
event.touches[0].clientX +
"," + event.touches[0].clientY + ")";
case "touchend":
output.innerHTML += "&br&Touch ended (" +
event.changedTouches[0].clientX + "," +
event.changedTouches[0].clientY + ")";
case "touchmove":
event.preventDefault(); //
output.innerHTML += "&br&Touch moved (" +
event.changedTouches[0].clientX + "," +
event.changedTouches[0].clientY + ")";
}}EventUtil.addHandler(document, "touchstart", handleTouchEvent);EventUtil.addHandler(document, "touchend", handleTouchEvent);EventUtil.addHandler(document, "touchmove", handleTouchEvent);触摸屏幕上的元素时,事件发生的顺序如下:touchstartmouseovermousemove
mousedownmouseupclicktouchend手势事件 当两个手指触摸屏幕时会产生手势,iOS中的Safari定义了3个手势事件: gesturestartgesturestart:一个手指已在屏幕上另一个手指又触摸屏幕gesturechange:当触摸屏幕的任何一个手指发生变化的时候gestureend:任何一个手指移开事件都冒泡 鼠标事件的标准属性都有 两个特殊事件:rotation、scale rotation表示手指变化引起的旋转角度,负值表示逆时针 scale表示两个手指间距离的变化,从1开始变function handleGestureEvent(event) {
var output = document.getElementById("output");
switch (event.type) {
case "gesturestart":
output.innerHTML = "Gesture started (rotation=" + event.rotation +
",scale=" + event.scale + ")";
case "gestureend":
output.innerHTML += "&br&Gesture ended (rotation=" + event.rotation +
",scale=" + event.scale + ")";
case "gesturechange":
output.innerHTML += "&br&Gesture changed (rotation=" + event.rotation +
",scale=" + event.scale + ")";
}}document.addEventListener("gesturestart", handleGestureEvent, false);document.addEventListener("gestureend", handleGestureEvent, false);document.addEventListener("gesturechange", handleGestureEvent, false);内存和性能在JS中添加到页面上的事件处理程序数量将直接关系到页面的整体运行性能。事件委托利用事件的冒泡特性,在DOM树种尽量高的层次上添加一个事件处理程序:EventUtil.addHandler(document, "click", function(event){
event = EventUtil.getEvent(event);
var target = EventUtil.getTarget(event);
switch(target.id){
case "myButton":
document.title = "I changed the document's title";
case "highDiv":
location.href = "";
case "myDiv":
alert("hi");
}});这样做优点很多只需要取得一个DOM元素或直接加在document上,快只添加了一个事件处理函数,内存占用小如果直接添加在document上,document不需要等待load事件,也就是说按钮只要出现立即可用移除事件处理程序事件与元素的连接越多,页面就越慢。限制事件数量刚才我们已经做了。另外就是在不需要的时候移除事件处理程序。 当我们移除或替换节点时,原有节点的事件处理程序却还在,这时最好手工将其事件解绑。如果一开始你的事件处理就像刚才那样写在了高层次的元素中,这个问题就不存在啦。 还有就是在我们卸载页面时,有的浏览器处理的并不好,页面被卸载了但是处理程序还在,来回来回切换打开的过程中内存里就多了很多没用或重复的事件。我们可以在onunload事件中移除所有事件处理程序。这就体现了将事件处理集中起来的优点——移除时很轻松。模拟事件通过JS来触发本该由浏览器触发的事件DOM中的事件模拟鼠标事件var div = document.getElementById("myDiv");//先创建一个事件,会返回一个特定的事件对象var event = document.createEvent("MouseEvents");//用各种参数初始化事件对象event.initMouseEvent("click", true, true, document.defaultView, 0, 0, 0, 0, 0,false, false, false, false, 0, null);//在目标元素上触发div.dispatchEvent(event);可以模拟下面这些事件UIEvents、MouseEvents、MutationEvents、HTMLEvents。具体的就不写了大体一致的思路。IE中的事件模拟一样的思路,方法不太一样var btn = document.getElementById("myBtn");var event = document.createEventObject();event.screenX = 100;event.screenY = 0;event.clientX = 0;event.clientY = 0;event.ctrlKey = false;event.altKey = false;event.shiftKey = false;event.button = 0;btn.fireEvent("onclick", event);
最新教程周点击榜
微信扫一扫}

我要回帖

更多关于 文本框输入字符长度 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信