您的位置:首页 > Web前端 > JavaScript

Javascript学习指南(第2版)笔记(三) 排错、调试、事件捕获

2010-05-29 09:25 686 查看
1、排错、调试

2、事件

3、Event对象

4、事件冒泡

5、事件句柄和 this

6、DOM Level 2事件模型

7、测验



1、排错、调试


Firebug是最常用的 Firefox开发工具,同时常用的 Web工具还有 Web Developer toolkit,该工具功能包括页面 HTML和 CSS代码的校验、可访问性检查、查看 CSS和 cookies、检查图像、查看 JavaScript修改后的页面源代码(包括动态源代码)。



2、事件



事件包括:用户界面事件(鼠标、键盘触发的)、逻辑事件(一个处理的结果)、和变化事件(修改文档的操作)。

事件句柄 (Event Handlers)

HTML 4.0 的新特性之一是能够使 HTML 事件触发浏览器中的行为,比如当用户点击某个 HTML 元素时启动一段 JavaScript。下面是一个属性列表,可将之插入 HTML 标签以定义事件的行为。

属性此事件发生在何时...IEFOW3C
onabort图像的加载被中断。419Yes
onblur元素失去焦点。319Yes
onchange域的内容被改变。319Yes
onclick当用户点击某个对象时调用的事件句柄。319Yes
ondblclick当用户双击某个对象时调用的事件句柄。419Yes
onerror在加载文档或图像时发生错误。419Yes
onfocus元素获得焦点。319Yes
onkeydown某个键盘按键被按下。31NoYes
onkeypress某个键盘按键被按下并松开。319Yes
onkeyup某个键盘按键被松开。319Yes
onload一张页面或一幅图像完成加载。319Yes
onmousedown鼠标按钮被按下。419Yes
onmousemove鼠标被移动。319Yes
onmouseout鼠标从某元素移开。419Yes
onmouseover鼠标移到某元素之上。319Yes
onmouseup鼠标按键被松开。419Yes
onreset重置按钮被点击。419Yes
onresize窗口或框架被重新调整大小。419Yes
onselect文本被选中。319Yes
onsubmit确认按钮被点击。319Yes
onunload用户退出页面。319Yes
注:HTML DOM Event 对象 http://www.w3school.com.cn/htmldom/dom_obj_event.asp[/i]
内联模式/内联注册模式

以属性的形式为 HTML元素添加属性的方法。

<body onload="var 1=23; i*=3; alert(i);">

<body onload="calcNumber();">

传统模式/传统注册模式

通过对象属性将一个函数指派为事件句柄。如果想禁用事件处理,那么可以将事件句柄的值赋为 null。

window.onload = calcNumber;

注:

在 DOM Level 0事件模型中,任何对象只允许指定一个事件句柄。如果你想针对某一特定对象的某个事件指定多个函数,则需要在事件句柄代码中列出他们:

内嵌模式:

<body onload="helloMsg(); helloTwice();">

传统模式:

function helloMsg() {

var helloString = "hello there";

alert(helloString);

helloTwice();

}

当要求浏览器停止执行事件行为,可以从事件句柄函数中返回 false值。



3、Event对象



Event对象是和所有事件相关的。它有一些用来提供事件相关信息的属性,如 Web页面中鼠标点击的位置。

IE将 Event视为 window对象的属性。当处理事件时,将通过程序访问 window对象,其所包含的数据也会相应的进行填充。

function mouseDown() {

var locString = "X = " + window.event.screenX + " Y = " + window.event.screenY;

alert(locString);

}

document.onmousedown = mouseDown;


在基于 Netscape的浏览器(如 Firefox、Mozilla、Opera和 Safari)中,获取 Event对象的方法是不同的:他将作为函数的一部分传入。

function mouseDown(theEvent) {

var locString = "X = " + theEvent.screenX + " Y = " + theEvent.screenY;

alert(locString);

}

document.onmousedown = mouseDown;


处理这些浏览器差异的方法之一是检查传入函数的 Event对象是否已经实例化。如果是,那么将这个 Event对象赋给一个局部变量;否则,将假定 window.event为该事件,并将其赋给这个局部变量。

function mouseDown(nsEvent) {

var theEvent = nsEvent ? nsEvent : window.event;    //判断 nsEvent对象是否已定义。定义则赋值,否则选择 window.event属性

var locString = "X = " + theEvent.screenX + " Y = " + theEvent.screenY;

alert(locString);

}

document.onmousedown = mouseDown;


鼠标 / 键盘属性

属性描述IEFOW3C
altKey返回当事件被触发时,"ALT" 是否被按下。619Yes
button返回当事件被触发时,哪个鼠标按钮被点击。619Yes
clientX返回当事件被触发时,鼠标指针的水平坐标。619Yes
clientY返回当事件被触发时,鼠标指针的垂直坐标。619Yes
ctrlKey返回当事件被触发时,"CTRL" 键是否被按下。619Yes
metaKey返回当事件被触发时,"meta" 键是否被按下。No19Yes
relatedTarget返回与事件的目标节点相关的节点。No19Yes
screenX返回当某个事件被触发时,鼠标指针的水平坐标。619Yes
screenY返回当某个事件被触发时,鼠标指针的垂直坐标。619Yes
shiftKey返回当事件被触发时,"SHIFT" 键是否被按下。619Yes
注:HTML DOM Event 对象 http://www.w3school.com.cn/htmldom/dom_obj_event.asp[/i]
注:

在 IE中,fromElement 对于 mouseover 和 mouseout 事件,fromElement 引用移出鼠标的元素。

而在 Mozilla/Firefox中,relatedTarget 返回与事件的目标节点相关的节点。

要解决浏览器差异,可以使用:

var oldElement = theEvent.fromElement ? theEvent.fromElement : theEvent.relatedTarget;



4、事件冒泡



如果你为多个嵌套的元素设置相同的事件句柄,会发生什么呢?他们将以什么样的顺序触发?如果你想使得一次只影响一个元素,那么如何保存触发事件句柄的事件呢?

要管理元素堆栈中的事件,其中一个方法就是众所周知的事件冒泡。在事件冒泡中,最内部的元素将首先触发该事件,然后堆栈内的下一个元素触发该事件,以此类推,直到最外面的元素。如果事件句柄被指定给所有元素,那么这些事件将依次被触发。

如果 div2在 div1内部,而 div1又在 document内部,三者都做了事件处理。当事件触发的时候,优先最里面的 div2元素,然后是 div1元素,最后是 document元素。

如果你有一个元素堆栈,并且只希望一个元素触发该事件句柄,那么你可以取消事件冒泡机制。如果在 IE中要取消一个事件冒泡,可以使用 IE中事件的 cancelBubble属性;对于 Mozilla而言,则应该使用事件的 stopPropagation方法。你可以先检查 stopPropagation方法是否存在,然后根据其结果确定使用哪种方法:

function stopEvent(evnt) {

if (evnt.stopPropagation) evnt.stopPropagation;

else evnt.cancelBubble = true;

}

//注:IE 7中调试出错,提示信息 "stopPropagation为空或不是对象"。




5、事件句柄和 this



this关键字表示的是当前调用的函数或者方法的所有者。对于一个全局变量而言,它表示的就是 window对象。对于一个对象的方法而言,它表示的就是该对象实例。而在一个事件句柄中,它表示的就是接收到该事件的元素。

document.getElementById("first").onmousedown = function() {

alert(this);    //在 Firefox中将输出 "[object HTMLDivElement]"

alert("first element event");

}




6、DOM Level 2事件模型


对于堆栈内元素的事件处理,还有一种被称为事件捕捉(event capturing)或 cascade-down的事件处理机制。对于前面这个包含3个元素的示例而言,事件将从最外面的元素开始触发:window -> div1 -> div2。

老事件模型和新的 DOM Level 2事件模型之间,主要区别:

a.新事件模型并不依赖于特定的事件来处理属性;

b.你可以对任何一个对象的任何一种事件注册多个事件句柄函数。

新的事件句柄提供的3个方法:

addEventListener,添加一个事件监听器;

removeEventListener,删除一个事件监听器;

dispatchEvent,分发一个新的事件。

示例:

object.addEventListener('event', eventFunction, boolean);

如 click或 load之类的事件是其第一参数;第二个参数是指定的事件句柄函数;第三个参数用来指定事件是以 cascade-down或者冒泡模式处理的。当第三个参数为 false时这个事件监听器将以冒泡模式处理,否则将把这个事件监听器改成事件捕捉模型。

function cascadeDown(evnt) {

alert("Capturing: " + this);

}

function bubbleUp(evnt) {

alert("Bubbling: " + this);

}

window.onload = setup;

function setup(evnt) {

//事件捕捉

document.addEventListener("click", cascadeDown, true);

document.forms[0].addEventListener("click", cascadeDown, true);

document.forms[0].elements[0].addEventListener("click", cascadeDown, true);

//事件冒泡

document.addEventListener("click", bubbleUp, false);

document.forms[0].addEventListener("click", bubbleUp, false);

document.forms[0].elements[0].addEventListener("click", bubbleUp, false);

}

/*

在 Firefox中,单击按钮将顺序生成6个对话框

Capturing: [object HTMLDocument]

Capturing: [object HTMLFormElement]

Capturing: [object HTMLInputElement]

Bubbling: [object HTMLInputElement]

Bubbling: [object HTMLFormElement]

Bubbling: [object HTMLDocument]

*/


如果你想停止事件执行时,可以在函数中调用 stopPropagation方法:

function cascadeDown(evnt) {

...

evnt.stopPropagation();

}

如果要彻底删除一个事件监听器,可以使用 removeEventListener方法:

document.removeEventListener("click", cascadeDown, true);

在 IE中,与 addEventListener和 removeEventListener方法相似的是 attachEvent和 detachEvent,对应语法是:

object.attachEvent("eventhandler", function);

第一个参数是事件句柄,第二个是其函数。detachEvent语法类似。

跨浏览器解决方案:

window.onload = setup;

window.onunload = cleanup;

function setup(evnt) {

var evtObject = document.getElementById("clickme");

//检查对象模型

if (evtObject.addEventListener) evtObject.addEventListener("click", clickMe, false);

else if (evtObject.attachEvent) evtObject.attachEvent("onclick", clickMe);

else if (evtObject.onclick) evtObject.onclick=clickMe;

}

/*清理

在 IE中,需要跟踪 window的 unload事件,然后调用 detachEvent方法清理,释放相应的内存

而 addEventListener方法使用的内存是无需清理的。

*/

function cleanup() {

var evtObject = document.getElementById("clickme");

if (evtObject.detachEvent) evtObject.detachEvent("onclick", clickMe);

}

function clickMe() {

alert("clickMe");

}


IE 属性

除了上面的鼠标/事件属性,IE 浏览器还支持下面的属性:

属性描述
cancelBubble如果事件句柄想阻止事件传播到包容对象,必须把该属性设为 true。
fromElement对于 mouseover 和 mouseout 事件,fromElement 引用移出鼠标的元素。
keyCode对于 keypress 事件,该属性声明了被敲击的键生成的 Unicode 字符码。对于 keydown 和 keyup 事件,它指定了被敲击的键的虚拟键盘码。虚拟键盘码可能和使用的键盘的布局相关。
offsetX,offsetY发生事件的地点在事件源元素的坐标系统中的 x 坐标和 y 坐标。
returnValue如果设置了该属性,它的值比事件句柄的返回值优先级高。把这个属性设置为 fasle,可以取消发生事件的源元素的默认动作。
srcElement对于生成事件的 Window 对象、Document 对象或 Element 对象的引用。
toElement对于 mouseover 和 mouseout 事件,该属性引用移入鼠标的元素。
x,y事件发生的位置的 x 坐标和 y 坐标,它们相对于用CSS动态定位的最内层包容元素。
注:HTML DOM Event 对象 http://www.w3school.com.cn/htmldom/dom_obj_event.asp[/i]

标准 Event 属性

下面列出了 2 级 DOM 事件标准定义的属性。

属性描述IEFOW3C
bubbles返回布尔值,指示事件是否是起泡事件类型。No19Yes
cancelable返回布尔值,指示事件是否可拥可取消的默认动作。No19Yes
currentTarget返回其事件监听器触发该事件的元素。No19Yes
eventPhase返回事件传播的当前阶段。Yes
target返回触发此事件的元素(事件的目标节点)。No19Yes
timeStamp返回事件生成的日期和时间。No19Yes
type返回当前 Event 对象表示的事件的名称。619Yes
注:HTML DOM Event 对象 http://www.w3school.com.cn/htmldom/dom_obj_event.asp

[/i]



7、测验



Q1:使用 DOM Level 0方法为 document的 click事件指定一个事件句柄函数。

A1:document.onclick = clickMe;

Q2:使用 DOM Level 2事件处理机制为 document添加 click事件句柄。

A2:document.addEventListener("click", clickMe, false);

Q3:如果使事件处理机制能安全运行所有浏览器?

A3:

if (evtObject.addEventListener) evtObject.addEventListener("click", clickMe, false);

else if (evtObject.attachEvent) evtObject.attachEvent("onclick", clickMe);

else if (evtObject.onclick) evtObject.onclick=clickMe;

Q4:对于为 document对象指定的 onclick事件句柄,如何知道是在屏幕的什么位置执行了单击操作?

A4:

如果使用 DOM Level 0事件处理系统,那么将无法使用 window对象的 event对象,也不能将其作为参数传给函数。

对于 DOM Level 2事件处理模型而言,event对象将会传给事件句柄函数,你可以通过 event对象访问其 screenX和 screenY属性。

Q5:使用 DOM Level 2事件系统,如何阻止从其他元素中冒泡上来的事件。

A5:

IE所支持的方法和绝大多数浏览器所支持的方法有所不同,因此你需要分别支持 IE和其他浏览器。你可以检查 event对象是否支持 stopPropagation方法。如果支持,则调用它;否则就将 cancelBubble属性的值设置为 true。

Q7:捕获 document对象的 keydown事件

A7:

window.onload = function() {

if (document.addEventListener) document.addEventListener("keydown", getKey, false);

else if (document.attachEvent) document.attachEvent("onkeydown", getKey);

else if (document.onkeydown) document.onkeydown=getKey;

}

function getKey(evnt) {

var theEvent = evnt ? evnt : window.event;

alert(theEvent.which);  //Firefox 返回值,IE 7提示 undefined

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: