具有交互性的JavaScript程序使用的是事件驱动的程序设计模型。
 
目前使用的有3种完全不同的不兼容的事件处理模型。
1、原始事件模型
(一种简单的事件处理模式)
一般把它看作0级DOM API的一部分内容,所有启用了JavaScript的浏览器都支持它,因此它具有可移植性。
 
2、标准事件模型
(一种强大的具有完整性的事件模型)
 2级DOM标准对它进行了标准化,除IE以外的所有浏览器都支持它。
3、IE事件模型
   想用高级事件处理特性的JavaScript程序设计者必须为IE浏览器编写特定的代码。
 
17.1 基本事件处理(原始事件模型)
 
17.1.1事件和事件类型
    在原始事件模型中,事件是浏览器内部提取的,JavaScript代码不能直接操作事件。
 
原始事件模型的事件类型:响应事件时调用的事件句柄名。
在此模型中,用HTML元素的属性(和相关的JavaScript对象的相应属性)设置事件处理代码。
 
如:
<input type="text" onclick="......."/>
document.getElementsByTag("input").onclick=.......;
 
事件句柄和支持它们的HTML元素
onbort                图像装被中断(img支持
onblur
onchange          获取焦点,尽管变了值后,失去焦点时触 发,input select textarea支持
onclick
oncbclick
onerror
onfocus
onkeydown
onkeypress
onkeyup
onload
onmousedown
onmousemove
onmouseout
onmouseover
onmouseup
onrest
onresize
onselect            选中文本 input textera支持
onsubmit
onunload
 
分类 1、原始事件(输入事件)由鼠标和键盘产生
2、高级事件:特定环境下发生,如onload
 
也可以分类为 设备相关 设备无关
17.1.2作为HTML属性的事件句柄会隐式声明一个函数。(前提是值为一段代码,而不是函数名称)
<input type="text" onclick="......."/>
17.1.3 作为JavaScript属性的事件句柄
document.getElementsByTag("input").onclick=.......;
这个属性必须全为小写,在此事件够本中,this引用发生事件的对象。
 
 
显式调用事件够本
由于JavaScript事件句柄属性的值是函数,所以可调用 如:
document.mform.onsubmit()
注:直接调用事件够本的方法并不是模拟事件发生时的真正状态,只是执行这个函数而已。
 
显式调用事件处理函数的原因之一是,可以用JavaScript扩展HTML代码定义的事件处理函数,假定想在用户点击
按钮时执行特殊的动作,但是又不想破坏HTML文档自身定义的onclick事件句柄。
可以先保存这个事件句柄函数,然后重新设置的时候,将这个函数,放入新的事件句柄函数当中,然后再在其后添加新的代码。
如:
var b=document.myform.mybutton;
var oldHandler=b.onclick;
function newHandler()
{
.....
}
b.onclick=function()
{
    oldHandler();
    newHandler();
}
注:现在大多浏览器多次设置事件句柄属性值,并不会覆盖上一个。只会叠加。
 
17.1.4事件句柄的返回值
通常,如果浏览器执行某种默认动作来响应一个事件,那么可以返回false阻止浏览器执行那个动作。
这些事件句柄是
onsubmit、onclick、onkeydown、onkeypress、onmousedown、onmouawup的onreset
注:事件句柄从来不要求显式地返回值。如果不返回值,就会发生默认的动作。
代码:
 代码:
<input type="text" id="name" /> window.onload = function () {
document.getElementById("name").onkeypress = function (event) {
if (event.keyCode >115)
{
return false;
}
}
}
17.1.5 事件句柄和this关键字
在事件句柄调用时,它是作为产生事件的元素的方法调用的,所以关键字this引用了那个目标元素。
 
 
 
17.1.6事件句柄的作用域
    定义为HTML属性的事件句柄,它所执行的作用域和其他函数的作用域不同。
JavaScript中的函数运行在词法作用域中。这意味着函数在定义它们的作用域中运行,而不在调用它们的作用域中运行。
定义 为HTML属性的事件句柄具有更加复杂的作用域链。它们的作用域链的头是调用对象,传递给事件句柄
的所有参数都是在这里定义的,它们和事件句柄主体中声明的局部变量一样,
但是事件句柄的作用域链中的下一个对象却并非全局对象,而是触发事件句柄的对象。
 
如:
<input type='button' onclick="var a=0;"/>
此a会被定义为此button对象属性
 
作用域如:
  <form>
<%-- this代表事件发生的目标对象 --%>
<input id="b1" type="button" value="Button1" onclick="alert(this.form.b2.value);" />
<%-- this代表事件发生的目标对象,所以可以省略this --%>
<input id="b2" type="button" value="Button2" onclick="alert(form.b1.value);" />
<%--form在此匿名函数的定义域(document) 当中,所以可以省略form --%>
<input id="b3" type="button" value="Button3" onclick="alert(b4.value);" />
<%--此匿名函数的定义的作用域为window.document当中,所以可以省略document --%>
<input id="b4" type="button" value="Button4" onclick="alert(getElementById('b3').value);" />
<%--此匿名函数的定义的作用域为window.document当中,但document对象也是运行在window当中,所以可以省略window --%>
</form>
注:DOM是作为BOM的组成部分存在的。
注:form本身应该属于document 同理 getElementById也是document对象的方法。
在此事件句柄函数中,寻找局部变量路径:调用对象,form对象,document对象,window对象。
由以上代码可以看出
此事件句柄的作用域链不会随定义句柄的对象终止,而且至少包括包含按钮的<form>
元素和包含表单的docuement对象。因为函数是在定义它的作用域中运行的。
作用域链的最终对象都是window对象,因为它总是在客户端javascript中。
 
以上b4的代码与以下相同
 var b4 = document.getElementById("b4");
b4.onclick = function () {
with (document) {
with (this.form) {
with (this) {
alert(b3.value);
}
}
}
}
注:以上出现的两个this,因为使用了with,所以分别代表document对象,与docuemnt.form对象。
 
因为在这种事件句柄当中 document对象比window对象更在作用域链前,所以如果在此事件句柄使用标识符 open()
而不是指定window,会默认使用document的open()方法,或者其它类似相关的情况。都会造成不同的情况。
 
防止这种意味的情况,使用这种句柄时,尽量简单,理想的方法是,让它们只调用在别的地方定义的全局函数。
 
注:以上讨论的作用域链都只是针对定义为HTML属性的事件句柄。
如果把一个函数赋予适当的javascript事件句柄属性来设置事件句柄,那么根本不涉及特殊的作用域链。
函数在定义它的作用域中执行,这几乎总是全局作用域(在此定义的作用域为window对象,而不是window.document对象),
如果是嵌套函数,情况会比较特殊。
 
以上待加深理解。 所有的节点元素对象都存在于DOM树中,DOM树的所有节点都存在于window当中。
全局独立作用域,且只有一个。
 
17.2      2级DOM中高级事件处理
 
17.2.1
在0级DOM事件模型中,当浏览器把事件分派给发生事件的文档元素时,如果对象具有合适的事件句柄,就运行这个句柄,不
用执行其他操作。
但在这种高级事件模型中,目标的每个祖先元素也有机会处理那个事件。
当事件发生在目标对象上时:
事件传播分三个阶段进行:
    第一、在捕捉(Capturing)阶段,事件从Document对象沿着文档树向下传播给目标节点(不再往下传播)。如果目标的任何一个
祖先(不是目标自身)专门注册了捕捉事件句柄,那么在事件传播的过程中,就会运行这些句柄。
 
    第二、下一个阶段发生在目标节点本身,直接注册在目标上的适合的事件句柄运行。(与0级事件模型提供的事件处理方法
相似。
    
    第三、起泡阶段(Bubbling),事件将从目标元素向上传播或起泡至Document对象的文档层次(直到document对象中的body 或者 html标记)。
 
注:所有事件都受事件传播的捕捉阶段的支配,但并非所有类型的事件都起泡。
一般,原始输入事件起泡(如click),而高级语义事件不起泡。
 
1、在事件传播的过程中,任何事件句柄都可调用表示那个事件的Event对象的stopPropagation()方法,停止事件的进一步传播。
 
2、有些事件会引发浏览器执行相关的默认动作。这样的默认动作只在事件传播的三个阶段都完成之后才分执行。可使用
Event对象的preventDefault()方法阻止默认动作发生。
 
关于事件传播有一个重要的细节。在0级模型中,只能为特定对象的特定类型的事件注册一个句柄。在2级模型中可以注册任意
多个处理函数,且将在事件传播的捕捉阶段或起泡阶段调用。
 
 
17.2.2 事件句柄的注册
    通过调用对象的addEventListener()方法为特定元素注册事件句柄。
移除使用removeEventListener()
注:此外的事件类型全为小写,且无前缀"on"
此方法有三个参数
a、事件类型名 如 click change focus等
b、事件句柄函数  在此事件句柄函数中,this关键字所引用的对象正是其上注册了这个句柄的对象
c、布尔值              true,则指定的事件句柄将在事件捕捉阶段用于捕捉事件。
                              false,则事件句柄就是常规的,当事件直接发生在对象上,或发生在元素的子女上,又向上起泡到该
                                        元素时,该句柄将被触发。
  <div id="div1" style="height:100px;height:40px;border:solid 1px red;">
<input id="b1" type="button" value="Button1" />
</div>
 window.onload = function () {
var b1 = document.getElementById("b1");
b1.addEventListener("click", function () {
alert("this is b1");
})
var div1 = document.getElementById("div1");
div1.addEventListener("click", function () {
alert("this is div1");
}, true) }
注:可以给同一个对象的同一个类型的事件,注册多个处理函数,在该类型的事件在那个对象上发生时,被注册的所有
函数都被调用(但注册的函数是同一个时,第一次注册后的所有注册都将被忽略。),且调用顺序不确定。
 
通过,临时注册一个事件处理函数,用完后迅速删除它比较有效。如mousedown mousemove mouseup 实现拖动元素。
如:代码
 function mousemoveFun(event) {
var left = event.clientX - div1.style.width.substring(0, div1.style.width.length - 2) / 2;
var top = event.clientY - div1.style.height.substring(0, div1.style.height.length - 2) / 2;
div1.style.left = left + "px";
div1.style.top = top + "px";
}
window.onload = function () {
var b1 = document.getElementById("b1");
var div1 = document.getElementById("div1");
var ismove = false;
div1.addEventListener("mousedown", function (event) {
document.addEventListener("mousemove", mousemoveFun, true);
ismove = true;
})
document.addEventListener("mouseup", function (event) {
if (!ismove) {
return;
}
ismove = false;
document.removeEventListener("mousemove", mousemoveFun, true);
var left = event.clientX - div1.style.width.substring(0, div1.style.width.length - 2) / 2;
var top = event.clientY - div1.style.height.substring(0, div1.style.height.length - 2) / 2;
div1.style.left = left + "px";
div1.style.top = top + "px";
}, true);
//注意:mousemove和mouseup事件的句柄被注册为捕捉事件句柄,因为用户移动鼠标的速度比跟跟随它移动的文档元素快,所以其中一些事件发生在
//原始目标元素外部,没有捕获,事件可能无法分配给正确的句柄
}
17.2.4  把对象注册为事件句柄
    在句柄函数中,调用某个对象的方法(并传递event参数),或直接把了此方法的对象直接传递给事件监听对象。
在此方法中,this引用的是方法所属的对象。
addEventListener()
代码:
  <input id="b1" type="button" value="Button1" />
var o = new Object();
o.value = "js对象";
o.func = function (event) {
//this引用的 o 而不是文档元素对象
alert(this.value);
}
window.onload = function () {
var b1 = document.getElementById("b1");
b1.addEventListener("click", function (event) {
o.func(event);
}, true);
}
 
17.2.5    事件模块和事件类型
    2级DOM标准是模块化的,可以用以下测试浏览器是否支持 EventAPI
document.implmentation.hasFeature("Events","2.0");
 
MutationEvents模块
当文档结构发生变化时,Mutation事件会触发。
 
表17.2 (所有以下模块共同组成 Event接口模块)
模块名                        事件接口                        事件类型
HTMLEvents                Event                    abort,blur,change,error,focus,
                                                                  load,rest,resize,sroll,select,submit,unload
MouseEvents            MouseEvent           click,mousedown,mousemove,mouseout 
                                                                  mouseover,mouseup
UIEevents                    UIEvent                 DOMActivate,DOMFocusIn,DOMFocusOut
 
MutationEvents
 
17.2.6 Event接口
当事件发生时,2级DOM API 提供了事件的额外信息(如何时何地发生的),作为传递给事件句柄的对象的属性。
每个事件模块有一个相关的事件接口,该接口声明了该事件类型的详细信息如 表17.2
 
1、HTMLEvent
    使用了Event接口,其它两个使用的是Event子接口。
有以下额外信息(属性)
type,target,currentTarget,eventPhase,timestamp,bubblues,cancelable
注:子接口除了实现Event接口的所有属性,还定义了自己特有的属性
2、UIEvent
    UIEvent是Event接口的子接口。
    view
    detail
3、MouseEvent
    MouseEvent接口继承Event接口和UIEvent接口的所有属性和方法。并且有自己特有的属性。
    button
    altKey,ctrlKey,metaKey,ShiftKey
    clientX,clientY
    screenX,screenY
    relatedTarget
4、MutationEvents
 
17.2.7 混合事件模型
    支持2级DOM的浏览器。都将0级事件注册自动使用addEventListener()方法
 
17.3 Internet Explorer事件模型 
17.3.1 IE Event对象
属于
type
srcElement
button
clientX,clientY
offsetX,offsetY
altKey,ctrlkey,shiftkey
keycode
formElement toElement
canclebubble
returnvalue
 
17.3.2
作为全局变量的IE Event对象
window.event 只有IE标准下,才为全局变量,其它标准为参数传递。
兼容:
function(event)
{
    var e=event||window.event;
}
 
17.3.3      IE事件句柄的注册
 
attachEvent()
detachEvent()
1、IE事件不支持事件传播
2、只有两个参数:事件类型(包含前缀on),句柄函数
3、被注册的句柄函数全作为全局函数调用,this代表window
4、同一个函数注册同一个事件中会被调用多次
 
17.3.4
IE中的事件起泡
(向上起泡)
IE Event没有stopPropagation(),只可采用以下方法来阻止向上进一步起泡传播。
window.event.cancelBubble=true;
只适用于当前事件,新事件生成时,自动重新恢复为false。
 
17.3.5 捕获鼠标事件
在处理鼠标事件时,需要使用到这两个方法
setcapture()
releasecaptuer()
 
17.3.6 attachEvent()和this关键字
this代表window,且IE中 Event无currentTarget,srcElement在事件起泡后,会发生改变。
如果想要编写一个通用的可以在任何元素上注册的事件句柄,且需要知道它注册于哪个元素上,不能使用
attachEvent()
必须使用:1、0级事件模型注册句柄
                   2、围绕句柄定义一个包围函数并注册这个包围函数
 如:
function genericHandler()
{
//...
}
var element=document.getElementById("div1")
element.onmouseover=genericHandler();
//或者
element.attachEvent("onmouseover",function()
{
        genericHandler.call(element,event);//明确指定函数的调用对象
});
17.3.8具有IE兼容性的事件模型(实例代码)
p414 
17.4鼠标事件 
 
17.5按钮事件
keydown keypress keyup
在keydown与Keyup之间,会产生多个keypress事件,
两个属性
keyCode            ASCII码
charCode         字符
IE中只有keyCode(keydown表示ASCII码,keypress时表示字符)
字符码转换:Sting.fromCharCode()
 
17.5.3
过滤键盘输入
通过return false
当keyup发生时,value值已经更新了(input textarea)
keypress发生后,把输入的字符回到自己的value属性后面。
 
17.6 onload事件
当文档完全载入之后,启动window.onload事件
可以为这事件注册事件句柄函数。
 
17.7合成事件(自定义事件)
2级DOM及IE事件模型都允许
1、在DOM事件模型中
使用Document.createEvent()创建一个合成事件,使用Event.initEvent() UIEvent.initUIEvent() 
或MouseEvent.initMouseEvent() 初始化事件,使用对象的dispathEvent() 分派(绑定)。
2、IE中
Document.createEventObject()创建 
对象方法 fireEvent()分派
本质就是创建一个自定义的事件。
注:使用dispatchEvent()和fireEvent()分派合成事件不需要排除,且是异步处理的。
注:随着浏览器的版本不断更新,更多event参数还得根据浏览器而定
代码:
 <input id="b1" type="button" value="Button1" />
var e;
window.onload = function () {
var b1 = document.getElementById("b1");
b1.addEventListener("click", function (event) {
dataEvent.receive("b1", e, function (event) {
alert(event.datatype + ":" + event.data);
});
}, true);
var e = dataEvent.send("b1", "name", "小三");
}
var dataEvent = {};
dataEvent.send = function (target, datatype, data) {
if (typeof target == "string") {
target = document.getElementById(target);
}
if (document.createEvent) {
var e = document.createEvent("Events");//此处使用的是接口名 Events UIEvents MouseEvents MutationEvents 有可能没有s
e.initEvent("dataavailable", true, false);//初始化自定义事件
}
else if (document.createEventObject) {
var e = document.createEventObject();
}
else return;
//自定义事件的一些属性
e.datatype = datatype;
e.data = data;
return e;
}
dataEvent.receive = function (target, event, handler) {
if (typeof target == "string")
{ target = document.getElementById(target); }
if (target.addEventListener)
{ target.addEventListener("dataavailable", handler, false); }
else if (target.attachEvent) {
target.attachEvent("ondataavailable", handler);
}
if (target.dispatchEvent) {
target.dispatchEvent(event);
}
else if (target.fireEvent) {
target.fireEvent("ondataavailable", event);
}
}

JavaScript 客户端JavaScript之事件(DOM API 提供模块之一)的更多相关文章

  1. JavaScript 客户端JavaScript之样式表操作(DOM API 提供模块之一)

    层叠样式 表和动态HTML   层叠样式表(CSS)是指定HTML文档或XML文档的表现的标准.     使用CSS和Javascript,可以创建出各种视觉效果,这些效果可以统称为动态HTML(DH ...

  2. JavaScript 客户端JavaScript之 Web浏览器的环境

    Web浏览器实现的Javascript,通过Web浏览器实现的JavaScript引入了大量可脚本化的对象(1.Web浏览器 2.HTML 3.HTML中的内容)  Web浏览器中的Javascrip ...

  3. JavaScript 客户端JavaScript之 脚本化文档

    客户端JavaScript的存在把静态HTML转变为交互式的Web应用程序,脚本化Web页面的内容正是JavaScript存在的理由.   一个文档对象模型或者说DOM就是一个API,它定义了如何访问 ...

  4. JavaScript 客户端JavaScript之脚本化HTTP(通过XMLHttpRequest)

    XMLHttpRequest对象的设计目的是为了处理由普通文本或XML组成的响应:但是,一个响应也可能是另外一种类型,如果用户代理(UA)支持这种内容类型的话.   大多数浏览的客户端JavaScri ...

  5. JavaScript 客户端JavaScript之 脚本化浏览器窗口

    1.计时器 客户端Javascript以全局函数setTimeOut().clearTimeOut().setInterval().clearInterval()提供这一功能.   前者是从运行的那一 ...

  6. JavaScript 客户端JavaScript之cookie和客户端持久性

    Document对象都有一个cookie属性,它使得JavaScript代码能够在用户的硬盘上持久地存储数据, 并且能够获取以这种方式存储的数据.客户端持久性是赋予WEB应用程序记忆力的一种简单方法. ...

  7. JavaScript 客户端JavaScript之Document对象中的表单和表单元素

    Form对象 代表一个HTML表单(document可以有多个表单元素) 表单访问 document.form[document.forms.length-1] 访问表单元素 document.for ...

  8. JavaScript DOM API初步(整理)

    文档对象模型 文档对象模型(Doucment Object Model,DOM)是表示文档(如HTML文档.XML文档)和访问.操作构成文档的各种元素的应用程序接口.在DOM中,HTML文档的层次结构 ...

  9. 前端开发【第6篇:JavaScript客户端(浏览器)】

    Web浏览器中的JavaScript 客户端JavaScript时间线 1.Web浏览器创建Document对象,并且开始解析web页面,解析HTML元素和它门的文本内容后添加Element对象和Te ...

随机推荐

  1. poj 2782 Bin Packing (贪心+二分)

    F - 贪心+ 二分 Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu   Description ...

  2. JavaBean与EJB的区别与应用

    JavaBean 是一种组件,它在内部有接口或有与其相关的属性,以便不同人在不同时间开发的 bean 可以询问和集成. EJB 是部署在服务器上的可执行组件或商业对象.有一个协议允许对其进行远程访问或 ...

  3. STM8S学习笔记-时钟控制2

    今天把时钟系统的最后部分,时钟安全系统(CSS)和时钟输出功能(CCO),做一个简答的说明. 1.时钟安全系统(以下简称CSS) CSS功能很简单,就是监控HSE是否实效(如果系统使用HSE作为主时钟 ...

  4. Netbeans8下 Weblogic EJB案例

    1:接口 @Remote public interface XgmZzsNssb {} 2:实现 @Stateless(mappedName="XgmZzsNssbImpl") @ ...

  5. angular2 学习笔记 ( rxjs 流 )

    RxJS 博大精深,看了好几篇文章都没有明白. 范围牵扯到了函数响应式开发去了... 我对函数式一知半解, 响应式更是第一次听到... 唉...不过日子还是得过...混着过先呗 我目前所理解的很浅,  ...

  6. VS2012 利用正则统计项目代码行数

    原文:VS2012 利用正则统计项目代码行数 #开头和/开头或者空行都不计入代码量,  搜索出来以后最后一行就是代码行数了:

  7. 【转】 Android 基于google Zxing实现对手机中的二维码进行扫描--不错

    原文网址:http://blog.csdn.net/xiaanming/article/details/14450809 转载请注明出处:http://blog.csdn.net/xiaanming/ ...

  8. 《算法问题实战策略》-chaper14-整数论

    Lucas定理: 在组合计数问题中,我们常面临组合数C(n,m)过大而无法直接计算的困境,那么这里的Lucas定理给出了一个较大组合数进行取余运算的一种递归算法. 什么是Lucas定理? Lucas定 ...

  9. Ubuntu环境下NFS服务器搭建

    看到鸟哥私房菜对NFS的介绍,就想试试玩一下.看起来步骤也很简单. 1.背景名词. NFS(Network File System) 作用:让所有的Unix-like 机器通过网络共享彼此的文件 局限 ...

  10. L - Cat VS Dog - HDU 3829(最大独立集)

    题意:有P个孩子,有的孩子喜欢猫不喜欢狗,有的喜欢狗不喜欢猫(喜欢的和不喜欢的一定是相相对立的动物),动物园有N只猫,M只狗,每个孩子都有喜欢的猫讨厌的狗(或者喜欢的狗讨厌的猫),现在动物园要送走一批 ...