的onclick的事件处理函数了,那么就把cancelbubble设置为false即可。[br] [br]二、 ie中拖动dom元素的例子[br]/*[br] 该函数由mousedown事件处理调用[br] 它为随后发生的mousemove和mouseup事件注册了临时的捕捉事件处理程序[br] 并用这些事件处理程序拖动指定的文档元素[br] 第二个参数必须是mousedown事件的事件对象[br]*/[br]function begindrag(elementtodrag,event)[br]{[br] //该元素当前位于何处[br] //该元素的样式性质必须具有left和top css属性[br] //此外,我们假定他们用象素做单位[br] //var x=parseint(elementtodrag.style.left);[br] //var y=parseint(elementtodrag.style.top); [br] //计算一个点和鼠标点击之间的距离,下面的嵌套的movehandler函数需要这些值[br] var deltax=event.clientx-parseint(elementtodrag.style.left);[br] var deltay=event.clienty-parseint(elementtodrag.style.top); [br]// 注册mousedown事件后发生的mousemove和mouseup事件的处理程序[br]// 注意,它们被注册为文档的捕捉事件处理程序[br]// 在鼠标按钮保持按下的状态的时候,这些事件处理程序保持活动的状态[br]// 在按钮被释放的时候,它们被删除[br] document.attachevent("onmousemove",movehandler);[br] document.attachevent("onmouseup",uphandler); [br] //我们已经处理了该事件,不要让别的元素看到它[br]event.cancelbubble=true;[br]event.returnvalue=false; [br] /*[br] 这是在元素被拖动时候捕捉mousemove事件的处理程序,它响应移动的元素 [br] */[br] function movehandler(e) [br] {[br] //把元素移动到当前的鼠标位置[br] e=window.event;[br] elementtodrag.style.left=(event.clientx-deltax)+"px";[br] elementtodrag.style.top=(event.clienty-deltay)+"px"; [br] //不要让别的元素看到该事件[br] event.cancelbubble=true; [br] } [br] /*[br] 该事件将捕捉拖动结束的时候发生的mouseup事件[br] */[br] function uphandler(e)[br] {[br] //注销事件处理程序[br] document.detachevent("onmouseup",uphandler);[br] document.detachevent("onmousemove",movehandler);} [br] event.cancelbubble=true;[br] } [br] 调用它的html文件代码:[br] [br] [br]
untitled page[br] [br] [br] [br]
[br]
[br] 拖动我 [br]
[br]
[br]
this is a test.testing,testing
[br]
[br] [br]三、 dom中的高级事件处理[br]ie 6中的事件处理,并不是w3c dom标准的事件处理模型,所以如果上述代码运行在mozilla firefox的浏览器中,就会失去作用,同时即将发布的ie 7也将支持w3c dom的二级标准,所以掌握dom的高级事件处理显得就很重要了,因为w3c dom二级标准是未来web的发展方向,同时w3c dom的api非常常用,为未来更加复杂的web开发提供了良好的基础。[br](一)事件处理程序的作用域和事件的传播[br] 在正式讨论dom高级事件处理之前,我们有必要了解一下事件处理程序的作用域。事件处理程序的作用域要比普通的函数作用域复杂很多。普通的函数作用域链比较容易,例如在一个普通函数中查找一个变量a,那么javascript解释器会先在该函数的调用对象中查找是否有a这个变量,如果没有,将会在作用域链的下一个对象,一般是全局对象中查找。但是事件处理程序没这么简单,特别是用html的属性定义的,它们的作用域链的头部是调用它们的对象,而下一个对象并不是全局对象,而是触发事件处理程序的对象。这样就会出现一个问题,window和document都有一个方法open(),如果open()前面不加修饰,那么在事件处理的函数中将会调用document.open()方法,而不是常用的window.open()方法,所以使用的时候应该明确指明是window.open()。[br](二)事件传播和注册事件处理程序[br]1.事件传播[br] 在二级dom标准中,事件处理程序比较复杂,当事件发生的时候,目标节点的事件处理程序就会被触发执行,但是目标节点的父节点也有机会来处理这个事件。事件的传播分为三个阶段,首先是捕捉阶段,事件从document对象沿着dom树向下传播到目标节点,如果目标的任何一个父节点注册了捕捉事件的处理程序,那么事件在传播的过程中就会首先运行这个程序。下一个阶段就是发生在目标节点自身了,注册在目标节点上的相应的事件处理程序就会执行;最后是起泡阶段,事件将从目标节点向上传回给父节点,同样,如果父节点有相应的事件处理程序也会处理。在ie中,没有捕捉的阶段,但是有起泡的阶段。可以用stoppropagation()方法来停止事件传播,也就是让其他元素对这个事件不可见,在ie 6中,就是把cancelbubble设置为true。[br]2.注册事件处理程序[br] 和ie一样,dom标准也有自己的事件处理程序,不过dom二级标准的事件处理程序比ie的强大一些,事件处理程序的注册用addeventlistner方法,该方法有三个参数,第一个是事件类型,第二个是处理的函数,第三个是一个布尔值,true表示制定的事件处理程序将在事件传播的阶段用于捕捉事件,否则就不捕捉,当事件发生在对象上才触发执行这个事件处理的函数,或者发生在该对象的字节点上,并且向上起泡到这个对象上的时候,触发执行这个事件处理的函数。例如:document.addeventlistener("mousemove",movehandler,true);就是在mousemove事件发生的时候,调用movehandler函数,并且可以捕捉事件。[br] 可以用addeventlistener为一个事件注册多个事件处理的程序,但是这些函数的执行顺序是不确定,并不像c#那样按照注册的顺序执行。[br] 在mozilla firefox中用addeventlistener注册一个事件处理程序的时候,this关键字就表示调用事件处理程序的文档元素,但是其他浏览器并不一定是这样,因为这不是dom标准,正确的做法是用currenttarget属性来引用调用事件处理程序的文档元素。[br]3.二级dom标准中的event[br] 和ie不同的是,w3c dom中的event对象并不是window全局对象下面的属性,换句话说,event不是全局变量。通常在dom二级标准中,event作为发生事件的文档对象的属性。event含有两个子接口,分别是uievent和mutationevent,这两个子接口实现了event的所有方法和属性,而mouseevent接口又是uievent的子接口,所以实现了uievent和event的所有方法和属性。下面,我们就看看event、uievent和mouseevent的主要属性和方法。[br] 1.event[br] type:事件类型,和ie类似,但是没有“on”前缀,例如单击事件只是“click”。[br] target:发生事件的节点。[br] currenttarget:发生当前正在处理的事件的节点,可能是target属性所指向的节点,也可能由于捕捉或者起泡,指向target所指节点的父节点。[br] eventphase:指定了事件传播的阶段。是一个数字。[br] timestamp:事件发生的时间。[br] bubbles:指明该事件是否起泡。[br] cancelable:指明该事件是否可以用preventdefault()方法来取消默认的动作。[br] preventdefault()方法:取消事件的默认动作;[br] stoppropagation()方法:停止事件传播。[br] 2.uievent[br] view:发生事件的window对象。[br] detail:提供事件的额外信息,对于单击事件、mousedown和mouseup事件都代表的是点击次数。[br] 3.mouseevent[br] button:一个数字,指明在mousedown、mouseup和单击事件中,鼠标键的状态,和ie中的button属性类似,但是数字代表的意义不一样,0代表左键,1代表中间键,2代表右键。[br] altkey、ctrlkey、shiftkey、metakey:和ie相同,但是ie没有最后一个。[br] clientx、clienty:和ie的含义相同,但是在dom标准中,这两个属性值都不考虑文档的滚动情况,也就是说,无论文档滚动到哪里,只要事件发生在窗口左上角,clientx和clienty都是0,所以在ie中,要想得到事件发生的坐标相对于文档开头的位置,要加上document.body.scrollleft和document.body.scrolltop。[br] screenx、screeny:鼠标指针相对于显示器左上角的位置,如果你想打开新的窗口,这两个属性很重要。[br] relatedtarget:和ie中的fromelement、toelement类似,除了对于mouseover和mouseout有意义外,其他的事件没什么意义。[br](三)兼容于两种主流浏览器的拖动dom元素的例子[br] 好了,刚才讲了这么多dom编程和ie中的事件,那么如何编写兼容ie和mozilla firefox两种主流浏览器的拖拽程序呢?代码如下:[br]function begindrag(elementtodrag,event)[br]{[br] var deltax=event.clientx-parseint(elementtodrag.style.left);[br] var deltay=event.clienty-parseint(elementtodrag.style.top);[br][color=#800000] //hgx注:个人觉得使用通过css的left/top属性来计算不是一个好方法,可以通过offserleft和offsertop得到。[/color][br]if(document.addeventlistener) [br]{[br] document.addeventlistener("mousemove",movehandler,true);[br] document.addeventlistener("mouseup",uphandler,true);[br]}[br]else if(document.attachevent)[br]{[br] document.attachevent("onmousemove",movehandler);[br] document.attachevent("onmouseup",uphandler);[br] [br]}[br] [br] if(event.stoppropagation) event.stoppropagation();[br] else event.cancelbubble=true;[br] if(event.preventdefault) event.preventdefault();[br] else event.returnvalue=false;[br] [br] function movehandler(e) [br] {[br] if (!e) e=window.event; //如果是ie的事件对象,那么就用window.event[br] //全局属性,否则就用dom二级标准的event对象。[/p]
[p][color=#800000]//hgx注:也可以这样:e = e || window.event;[/color][br] elementtodrag.style.left=(event.clientx-deltax)+"px";[br] elementtodrag.style.top=(event.clienty-deltay)+"px";[br] [br] if(event.stoppropagation) event.stoppropagation();[br] else event.cancelbubble=true;[br] [br] }[br] [br] function uphandler([br]e)[br] {[br] if(document.removeeventlistener)[br] {[br] document.removeeventlistener("mouseup",uphandler,true);[br] document.removeeventlistener("mousemove",movehandler,true);}[br] else[br] {[br] document.detachevent("onmouseup",uphandler);[br] document.detachevent("onmousemove",movehandler);}[br] }[br] if(event.stoppropagation) event.stoppropagation();[br] else event.cancelbubble=true;[br] [br] }[/p]
该文章在 2010/4/24 11:24:04 编辑过