- 浏览: 324710 次
- 性别:
- 来自: 济南
-
文章分类
- 全部博客 (221)
- J2SE心得 (4)
- 经典帖子 (8)
- 亲身经历 (9)
- SSH框架 (12)
- 数据库 (10)
- java基础知识 (41)
- java解惑 (17)
- 软件测试 (0)
- JSP (6)
- JavaScript (8)
- jQuery学习 (12)
- 硬件知识 (1)
- 工具类 (14)
- 面试专题 (4)
- Struts2专题(学习) (14)
- Spring源码分析专题(学习) (15)
- JavaScript专题(学习) (8)
- ExtJs专题(学习) (6)
- Java Web快速入门——全十讲 (10)
- web前台 (1)
- J2ME手机方面 (1)
- 积累整理 (1)
- MyEclipse工具篇 (10)
- oracle (1)
- Android基础 (1)
最新评论
-
youjianbo_han_87:
上传成功后,无法跳转到success页面,会报2038和404 ...
Struts2使用FlashFileUpload.swf实现批量文件上传 -
showzh:
...
MyEclipse 怎么安装SVN插件 -
wpf523:
赞一个啊,楼主加油
一些比较复杂的运算符(二) -
独步天下:
request.getSession().getAttribute() 和request.getSession().setAttribute() -
HelloJava1234:
thank you
怎么改变MyEclipse默认的jsp打开方式
事件(上)
(不好意思,又是标题党)
JavaScript事件列表 | ||
事件 | 解说 | |
一般事件 | onclick | 鼠标点击时触发此事件 |
ondblclick | 鼠标双击时触发此事件 | |
onmousedown | 按下鼠标时触发此事件 | |
onmouseup | 鼠标按下后松开鼠标时触发此事件 | |
onmouseover | 当鼠标移动到某对象范围的上方时触发此事件 | |
onmousemove | 鼠标移动时触发此事件 | |
onmouseout | 当鼠标离开某对象范围时触发此事件 | |
onkeypress | 当键盘上的某个键被按下并且释放时触发此事件. | |
onkeydown | 当键盘上某个按键被按下时触发此事件 | |
onkeyup | 当键盘上某个按键被按放开时触发此事件 | |
页面相关事件 | onabort | 图片在下载时被用户中断 |
onbeforeunload | 当前页面的内容将要被改变时触发此事件 | |
onerror | 出现错误时触发此事件 | |
onload | 页面内容完成时触发此事件 | |
onmove | 浏览器的窗口被移动时触发此事件 | |
onresize | 当浏览器的窗口大小被改变时触发此事件 | |
onscroll | 浏览器的滚动条位置发生变化时触发此事件 | |
onstop | 浏览器的停止按钮被按下时触发此事件或者正在下载的文件被中断 | |
oncontextmenu | 当弹出右键上下文菜单时发生 | |
onunload | 当前页面将被改变时触发此事件 | |
表单相关事件 | onblur | 当前元素失去焦点时触发此事件 |
onchange | 当前元素失去焦点并且元素的内容发生改变而触发此事件 | |
onfocus | 当某个元素获得焦点时触发此事件 | |
onreset | 当表单中RESET的属性被激发时触发此事件 | |
onsubmit | 一个表单被递交时触发此事件 |
了解上面的事件如此简单,那么事件还有什么可讲的呢?
问题一:每个事件只能注册一个函数
- var oDiv = document.getElementById("oDiv");
- oDiv.onclick = fn1;
- oDiv.onclick =fn2;
- function fn1() {alert("我被覆盖了!")}
- function fn2() {alert("只有我被执行到!")}
var oDiv = document.getElementById("oDiv"); oDiv.onclick = fn1; oDiv.onclick =fn2; function fn1() {alert("我被覆盖了!")} function fn2() {alert("只有我被执行到!")}
解决方案一:
obj.onclick = function () { fn1(); fn2(); fn3(); };
缺陷一:需要将所有函数一次添加进去,不能在运行时添加
缺陷二:在事件处理函数中this将指向window,而不是obj
解决方案二:
- function addEvent(fn,evtype,obj) {
- //obj是要添加事件的HTML元素对象
- //evtype是事件名字,不包含on前缀,因为每个都有on,所以写个on是多余的
- //fn是事件处理函数
- var oldFn;
- if (obj["on"+evtype] instanceof Function) {
- oldFn = obj["on"+evtype];//当添加函数时,如果已注册过了,则将其保存起来
- }
- obj["on"+evtype]=function () {
- if (oldFn) {
- oldFn.call(this);
- }
- fn.call(this);//使用call方法,使事件处理函数中的this仍指向obj
- };
- }
function addEvent(fn,evtype,obj) { //obj是要添加事件的HTML元素对象 //evtype是事件名字,不包含on前缀,因为每个都有on,所以写个on是多余的 //fn是事件处理函数 var oldFn; if (obj["on"+evtype] instanceof Function) { oldFn = obj["on"+evtype];//当添加函数时,如果已注册过了,则将其保存起来 } obj["on"+evtype]=function () { if (oldFn) { oldFn.call(this); } fn.call(this);//使用call方法,使事件处理函数中的this仍指向obj }; }
这样已经解决了问题,但如何删除事件呢?如果直接将对象的onevtype这类的属性赋值为null将会删除所有的事件处理函数!
解决方案二的修改版:先将事件存储起来,存储在对象的__EventHandles属性里面
- eventHandlesCounter=1;//计数器,将统计所有添加进去的函数的个数,0位预留作其它用
- function addEvent(fn,evtype,obj) {
- if (!fn.__EventID) {//__EventID是给函数加的一个标识,见下面给函数添加标识的部分
- fn.__EventID=eventHandlesCounter++;
- //使用一个自动增长的计数器作为函数的标识以保证不会重复
- }
- if (!obj.__EventHandles) {
- obj.__EventHandles=[];//当不存在,也就是第一次执行时,创建一个,并且是数组
- }
- if (!obj.__EventHandles[evtype]) {//将所有事件处理函数按事件类型分类存放
- obj.__EventHandles[evtype]={};//当不存在时也创建一个散列表
- if (obj["on"+evtype] instanceof Function) {
- //查看是否已经注册过其它函数
- //如果已经注册过,则将以前的事件处理函数添加到下标为0的预留的位置
- obj.__EventHandles[evtype][0]=obj["on"+evtype];
- obj["on"+evtype]=handleEvents;//使用handleEvents集中处理所有的函数
- }
- }
- obj.__EventHandles[evtype][fn.__EventID]=fn;
- //如果函数是第一次注册为事件处理函数,那么它将被添加到表中,函数的标识作为下标
- //如果函数已经注册过相同对象的相同事件了,那么将覆盖原来的而不会被添加两次
- function handleEvents() {
- var fns = obj.__EventHandles[evtype];
- for (var i in fns) {
- fns[i].call(this);
- }
- }
- }
eventHandlesCounter=1;//计数器,将统计所有添加进去的函数的个数,0位预留作其它用 function addEvent(fn,evtype,obj) { if (!fn.__EventID) {//__EventID是给函数加的一个标识,见下面给函数添加标识的部分 fn.__EventID=eventHandlesCounter++; //使用一个自动增长的计数器作为函数的标识以保证不会重复 } if (!obj.__EventHandles) { obj.__EventHandles=[];//当不存在,也就是第一次执行时,创建一个,并且是数组 } if (!obj.__EventHandles[evtype]) {//将所有事件处理函数按事件类型分类存放 obj.__EventHandles[evtype]={};//当不存在时也创建一个散列表 if (obj["on"+evtype] instanceof Function) { //查看是否已经注册过其它函数 //如果已经注册过,则将以前的事件处理函数添加到下标为0的预留的位置 obj.__EventHandles[evtype][0]=obj["on"+evtype]; obj["on"+evtype]=handleEvents;//使用handleEvents集中处理所有的函数 } } obj.__EventHandles[evtype][fn.__EventID]=fn; //如果函数是第一次注册为事件处理函数,那么它将被添加到表中,函数的标识作为下标 //如果函数已经注册过相同对象的相同事件了,那么将覆盖原来的而不会被添加两次 function handleEvents() { var fns = obj.__EventHandles[evtype]; for (var i in fns) { fns[i].call(this); } } }
使用上面的函数已经可以在一个对象添加多个事件处理函数,在函数内部this关键字也指向了相应的对象,并且这些函数都被作了标识,那么移除某个事件处理函数就是轻而易举的了!
- //使用传统方法:obj.onevtype = null;但这样会移除所有的事件处理函数
- function delEvent(fn,evtype,obj) {
- if (!obj.__EventHandles || !obj.__EventHandles[evtype] || !fn.__EventID) {
- return false;
- }
- if (obj.__EventHandles[evtype][fn.__EventID] == fn) {
- delete obj.__EventHandles[evtype][fn.__EventID];
- }
- }
//使用传统方法:obj.onevtype = null;但这样会移除所有的事件处理函数 function delEvent(fn,evtype,obj) { if (!obj.__EventHandles || !obj.__EventHandles[evtype] || !fn.__EventID) { return false; } if (obj.__EventHandles[evtype][fn.__EventID] == fn) { delete obj.__EventHandles[evtype][fn.__EventID]; } }
-------------------------------------------------新手的分隔线----------------------------------------------------------------
事件(下)
事件对象——Event
事件对象是用来记录一些事件发生时的相关信息的对象。事件对象只有事件发生时才会产生,并且只能是事件处理函数内部访问,在所有事件处理函数运行结束后,事件对象就被销毁!
访问事件对象:W3C DOM方法与IE专用方法
- //W3C DOM把事件对象作为事件处理函数的第一个参数传入进去
- document.onclick = function (evt) {//这样,事件对象只能在对应的事件处理函数内部可以访问到
- alert(evt);
- };
- //IE将事件对象作为window对象的一个属性(相当于全局变量)
- //貌似全局对象,但是只有是事件发生时才能够访问
- alert(window.event);//null
- window.onload = function () {
- alert(window.event);
- };
//W3C DOM把事件对象作为事件处理函数的第一个参数传入进去 document.onclick = function (evt) {//这样,事件对象只能在对应的事件处理函数内部可以访问到 alert(evt); }; //IE将事件对象作为window对象的一个属性(相当于全局变量) //貌似全局对象,但是只有是事件发生时才能够访问 alert(window.event);//null window.onload = function () { alert(window.event); };
事件对象的属性及方法
button | Integer | R |
对于特定的鼠标事件,表示按下的鼠标按钮,该属性仅可以在mouseup与mousedown事件中访问。W3C 规定:0表示按下了左键,1表示按下了中键,2表示按下了右键,相当于对于鼠标键从左到右进行的编号,而编号从0开始; 而IE有另外一套规定:0表示没有任何键按下,1表示左键,2表示右键,4表示中键,而其它按键的组合则只要将键码相加即可,如:同时按下左右键时button值为3 |
clientX | Integer | R | 事件发生时,鼠标在客户端区域的X坐标,客户端区域是指页面可视区域 |
clientY | Integer | R | 事件发生时,鼠标在客户端区域的Y坐标 |
screenX | Integer | R(IE) R/W(W3C) | 相对于屏幕的鼠标X坐标 |
screenY | Integer | R(IE) R/W(W3C) | 相对于屏幕的鼠标Y坐标 |
x(仅IE) | Integer | R | 鼠标相对于引起事件的元素的父元素的X坐标 |
y(仅IE) | Integer | R | 鼠标相对于引起事件的元素的父元素的Y坐标 |
offsetX(仅IE) layerX(仅W3C) | Integer | R | 鼠标相对于引起事件的对象的X坐标 |
offsetY(仅IE) layerY(仅W3C) | Integer | R | 鼠标相对于引起事件的对象的Y坐标 |
pageX(仅W3C) | Integer | R | 鼠标相对于页面的X坐标 |
pageY(仅W3C) | Integer | R | 鼠标相对于页面的Y坐标 |
altKey | Boolean | R | true表示按下了ALT键;false表示没有按下 |
ctrlKey | Boolean | R | true表示按下了CTROL,false表示没有 |
shiftKey | Boolean | R | true表示按下了shift,false表示没有 |
keyCode | Integer | R/W(IE) R(W3C) | 对于keypress事件,表示按下按钮的Unicode字符;对于keydown/keyup事件 ,表示按下按钮的数字代号 |
charCode(仅W3C) | Integer | R | 在keypress事件中所按键的字符Unicode编码,如果不是字符键,则该属性为0,并且,当CapsLock打开与关闭时charCode的值也对应着大小写字母 |
srcElement(IE) target(W3C) | Element | R | 引起事件的元素 | ||||||
fromElement(仅IE) | Element | R | 某些鼠标事件中(mouseover与mouseout),鼠标所离开的元素 | ||||||
toElement(仅IE) | Element | R | 某些鼠标事件中(mouseover与mouseout),鼠标所进入的元素 | ||||||
relatedTarget(仅W3C) | Element | R | 某些鼠标事件中(mouseover与mouseout),返回与事件的目标节点相关的节点。 | ||||||
repeat(仅IE) | Boolean | R | 如果不断触发keydown事件,则为true,否则为false | ||||||
returnValue(仅IE) | Boolean | R/W | 将其设为false表示以取消事件的默认动作 | ||||||
preventDefault(仅W3C) | Function | R | 执行方法以取消事件的默认动作 | ||||||
type | String | R | 事件的名称,不带on前缀 | ||||||
cancelable(仅W3C ) | Boolean | R | 当为true表示事件的默认动作可以被取消(用preventDefault方法取消) | ||||||
cancelBubble(仅IE) | Boolean | R/W | 将其设置为true将取消事件冒泡 | ||||||
stopPropagation(仅W3C) | Function | R | 执行方法取消事件冒泡 | ||||||
bubbles(仅W3C) | Boolean | R | 返回true表示事件是冒泡类型 | ||||||
eventPhase(仅W3C) | Integer | R | 返回事件传播的当前阶段。它的值是下面的三个常量之一,它们分别表示捕获阶段、在目标对象上时和起泡阶段:
|
||||||
timeStamp (仅W3C) | Long | R | 返回一个时间戳。指示发生事件的日期和时间(从 epoch 开始的毫秒数)。epoch 是一个事件参考点。在这里,它是客户机启动的时间。并非所有系统都提供该信息,因此,timeStamp 属性并非对所有系统/事件都是可用的。 |
取得事件对象及取得事件目标对象
- document.onclick =function (evt) {
- evt = evt || window.event;//在IE中evt会是undefined
- //而支持W3C DOM事件的浏览器中事件对象将会作为事件处理函数的第一个参数
- var targetElement = evt.target || evt.srcElement;
- //IE中事件对象没有target属性
- };
document.onclick =function (evt) { evt = evt || window.event;//在IE中evt会是undefined //而支持W3C DOM事件的浏览器中事件对象将会作为事件处理函数的第一个参数 var targetElement = evt.target || evt.srcElement; //IE中事件对象没有target属性 };
阻止事件发生时浏览器的默认行为
- document.onclick = function (evt) {
- evt = evt || window.event;
- var target = evt.target || evt.srcElement;
- if (!target) {
- return;
- }
- if (target.tagName=="A" && target.href) {
- //使用传统的方法取消事件默认行为必须使用return false
- //但使用了return ,函数便终止了运行,可以使用事件对象来取消
- if (window.event) {//IE
- window.event.returnValue = false;
- } else {
- evt.preventDefault();
- }
- window.open(target.href,"newWindow");
- //这样让所有的链接在新窗口打开
- }
- };
document.onclick = function (evt) { evt = evt || window.event; var target = evt.target || evt.srcElement; if (!target) { return; } if (target.tagName=="A" && target.href) { //使用传统的方法取消事件默认行为必须使用return false //但使用了return ,函数便终止了运行,可以使用事件对象来取消 if (window.event) {//IE window.event.returnValue = false; } else { evt.preventDefault(); } window.open(target.href,"newWindow"); //这样让所有的链接在新窗口打开 } };
事件传播——冒泡与捕获
DOM事件标准定义了两种事件流,这两种事件流有着显著的不同并且可能对你的应用有着相当大的影响。这两种事件流分别是捕获和冒泡。和许多Web技术一样,在它们成为标准之前,Netscape和微软各自不同地实现了它们。Netscape选择实现了捕获事件流,微软则实现了冒泡事件流。幸运的是,W3C决定组合使用这两种方法,并且大多数新浏览器都遵循这两种事件流方式。
默认情况下,事件使用冒泡事件流,不使用捕获事件流。然而,在Firefox和Safari里,你可以显式的指定使用捕获事件流,方法是在注册事件时传入useCapture参数,将这个参数设为true。
冒泡事件流
当事件在某一DOM元素被触发时,例如用户在客户名字节点上点击鼠标,事件将跟随着该节点继承自的各个父节点冒泡穿过整个的DOM节点层次,直到它遇到依附有该事件类型处理器的节点,此时,该事件是onclick事件。在冒泡过程中的任何时候都可以终止事件的冒泡,在遵从W3C标准的浏览器里可以通过调用事件对象上的stopPropagation()方法,在Internet Explorer里可以通过设置事件对象的cancelBubble属性为true。如果不停止事件的传播,事件将一直通过DOM冒泡直至到达文档根。
捕获事件流
事件的处理将从DOM层次的根开始,而不是从触发事件的目标元素开始,事件被从目标元素的所有祖先元素依次往下传递。在这个过程中,事件会被从文档根到事件目标元素之间各个继承派生的元素所捕获,如果事件监听器在被注册时设置了useCapture属性为true,那么它们可以被分派给这期间的任何元素以对事件做出处理;否则,事件会被接着传递给派生元素路径上的下一元素,直至目标元素。事件到达目标元素后,它会接着通过DOM节点再进行冒泡。
现代事件绑定方法
针对如上节课所讨论的,使用传统事件绑定有许多缺陷,比如不能在一个对象的相同事件上注册多个事件处理函数。而浏览器和W3C也并非没有考虑到这一点,因此在现代浏览器中,它们有自己的方法绑定事件。
W3C DOM
- obj.addEventListener(evtype,fn,useCapture)——W3C提供的添加事件处理函数的方法。obj是要添加事件的对象,evtype是事件类型,不带on前缀,fn是事件处理函数,如果useCapture是true,则事件处理函数在捕获阶段被执行,否则在冒泡阶段执行
- obj.removeEventListener(evtype,fn,useCapture)——W3C提供的删除事件处理函数的方法
微软IE方法
- obj.attachEvent(evtype,fn)——IE提供的添加事件处理函数的方法。obj是要添加事件的对象,evtype是事件类型,带on前缀,fn是事件处理函数,IE不支持事件捕获
- obj.detachEvent(evtype,fn,)——IE提供的删除事件处理函数的方法,evtype包含on前缀
整合两者的方法
- function addEvent(obj,evtype,fn,useCapture) {
- if (obj.addEventListener) {
- obj.addEventListener(evtype,fn,useCapture);
- } else {
- obj.attachEvent("on"+evtype,fn);//IE不支持事件捕获
- } else {
- obj["on"+evtype]=fn;//事实上这种情况不会存在
- }
- }
- function delEvent(obj,evtype,fn,useCapture) {
- if (obj.removeEventListener) {
- obj.removeEventListener(evtype,fn,useCapture);
- } else {
- obj.detachEvent("on"+evtype,fn);
- } else {
- obj["on"+evtype]=null;
- }
- }
function addEvent(obj,evtype,fn,useCapture) { if (obj.addEventListener) { obj.addEventListener(evtype,fn,useCapture); } else { obj.attachEvent("on"+evtype,fn);//IE不支持事件捕获 } else { obj["on"+evtype]=fn;//事实上这种情况不会存在 } } function delEvent(obj,evtype,fn,useCapture) { if (obj.removeEventListener) { obj.removeEventListener(evtype,fn,useCapture); } else { obj.detachEvent("on"+evtype,fn); } else { obj["on"+evtype]=null; } }
其它兼容性问题:IE不支持事件捕获?很抱歉,这个没有办法解决!但IE的attach方法有个问题,就是使用attachEvent时在事件处理函数内部,this指向了window,而不是obj!当然,这个是有解决方案的!
- function addEvent(obj,evtype,fn,useCapture) {
- if (obj.addEventListener) {
- obj.addEventListener(evtype,fn,useCapture);
- } else {
- obj.attachEvent("on"+evtype,function () {
- fn.call(obj);
- });
- } else {
- obj["on"+evtype]=fn;//事实上这种情况不会存在
- }
- }
function addEvent(obj,evtype,fn,useCapture) { if (obj.addEventListener) { obj.addEventListener(evtype,fn,useCapture); } else { obj.attachEvent("on"+evtype,function () { fn.call(obj); }); } else { obj["on"+evtype]=fn;//事实上这种情况不会存在 } }
但IE的attachEvent方法有另外一个问题,同一个函数可以被注册到同一个对象同一个事件上多次,解决方法:抛弃IE的 attachEvent方法吧!IE下的attachEvent方法不支持捕获,和传统事件注册没多大区别(除了能绑定多个事件处理函数),并且IE的 attachEvent方法存在内存泄漏问题!
addEvent,delEvent现代版
- function addEvent(obj,evtype,fn,useCapture) {
- if (obj.addEventListener) {//优先考虑W3C事件注册方案
- obj.addEventListener(evtype,fn,!!useCapture);
- } else {//当不支持addEventListener时(IE),由于IE同时也不支持捕获,所以不如使用传统事件绑定
- if (!fn.__EventID) {fn.__EventID = addEvent.__EventHandlesCounter++;}
- //为每个事件处理函数分配一个唯一的ID
- if (!obj.__EventHandles) {obj.__EventHandles={};}
- //__EventHandles属性用来保存所有事件处理函数的引用
- //按事件类型分类
- if (!obj.__EventHandles[evtype]) {//第一次注册某事件时
- obj.__EventHandles[evtype]={};
- if (obj["on"+evtype]) {//以前曾用传统方式注册过事件处理函数
- (obj.__EventHandles[evtype][0]=obj["on"+evtype]).__EventID=0;//添加到预留的0位
- //并且给原来的事件处理函数增加一个ID
- }
- obj["on"+evtype]=addEvent.execEventHandles;
- //当事件发生时,execEventHandles遍历表obj.__EventHandles[evtype]并执行其中的函数
- }
- }
- }
- addEvent.__EventHandlesCounter=1;//计数器,0位预留它用
- addEvent.execEventHandles = function (evt) {//遍历所有的事件处理函数并执行
- if (!this.__EventHandles) {return true;}
- evt = evt || window.event;
- var fns = this.__EventHandles[evt.type];
- for (var i in fns) {
- fns[i].call(this);
- }
- };
- function delEvent(obj,evtype,fn,useCapture) {
- if (obj.removeEventListener) {//先使用W3C的方法移除事件处理函数
- obj.removeEventListener(evtype,fn,!!useCapture);
- } else {
- if (obj.__EventHandles) {
- var fns = obj.__EventHandles[evtype];
- if (fns) {delete fns[fn.__EventID];}
- }
- }
- }
function addEvent(obj,evtype,fn,useCapture) { if (obj.addEventListener) {//优先考虑W3C事件注册方案 obj.addEventListener(evtype,fn,!!useCapture); } else {//当不支持addEventListener时(IE),由于IE同时也不支持捕获,所以不如使用传统事件绑定 if (!fn.__EventID) {fn.__EventID = addEvent.__EventHandlesCounter++;} //为每个事件处理函数分配一个唯一的ID if (!obj.__EventHandles) {obj.__EventHandles={};} //__EventHandles属性用来保存所有事件处理函数的引用 //按事件类型分类 if (!obj.__EventHandles[evtype]) {//第一次注册某事件时 obj.__EventHandles[evtype]={}; if (obj["on"+evtype]) {//以前曾用传统方式注册过事件处理函数 (obj.__EventHandles[evtype][0]=obj["on"+evtype]).__EventID=0;//添加到预留的0位 //并且给原来的事件处理函数增加一个ID } obj["on"+evtype]=addEvent.execEventHandles; //当事件发生时,execEventHandles遍历表obj.__EventHandles[evtype]并执行其中的函数 } } } addEvent.__EventHandlesCounter=1;//计数器,0位预留它用 addEvent.execEventHandles = function (evt) {//遍历所有的事件处理函数并执行 if (!this.__EventHandles) {return true;} evt = evt || window.event; var fns = this.__EventHandles[evt.type]; for (var i in fns) { fns[i].call(this); } }; function delEvent(obj,evtype,fn,useCapture) { if (obj.removeEventListener) {//先使用W3C的方法移除事件处理函数 obj.removeEventListener(evtype,fn,!!useCapture); } else { if (obj.__EventHandles) { var fns = obj.__EventHandles[evtype]; if (fns) {delete fns[fn.__EventID];} } } }
标准化事件对象
IE的事件对象与W3C DOM的事件对象有许多不一样的地方,解决的最好的方法就是调整IE的事件对象,以使它尽可能的与标准相似!下表列出了IE事件对象中一些和W3C DOM名称或值不一样但含义相同的属性
button——按键编码为:0-左键,1-中键,2-右键 | button——按键编码为:1-左键,2-右键,4-中键 |
charCode | 没有对应属性,但可以用keyCode来代替 |
preventDefault | 没有对应方法,但可以将event对象的returnValue设为false来模拟 |
target | srcElement |
relatedTarget | fromElement与toElement |
stopPropagation | 没有对应方法,但可以通过将event对象的cancelBubble属性设为true来模拟 |
总结出fixEvent函数
- function fixEvent(evt) {
- if (!evt.target) {
- evt.target = evt.srcElement;
- evt.preventDefault = fixEvent.preventDefault;
- evt.stopPropagation = fixEvent.stopPropagation;
- if (evt.type == "mouseover") {
- evt.relatedTarget = evt.fromElement;
- } else if (evt.type =="mouseout") {
- evt.relatedTarget = evt.toElement;
- }
- evt.charCode = (evt.type=="keypress")?evt.keyCode:0;
- evt.eventPhase = 2;//IE仅工作在冒泡阶段
- evt.timeStamp = (new Date()).getTime();//仅将其设为当前时间
- }
- return evt;
- }
- fixEvent.preventDefault =function () {
- this.returnValue = false;//这里的this指向了某个事件对象,而不是fixEvent
- };
- fixEvent.stopPropagation =function () {
- this.cancelBubble = true;
- };
function fixEvent(evt) { if (!evt.target) { evt.target = evt.srcElement; evt.preventDefault = fixEvent.preventDefault; evt.stopPropagation = fixEvent.stopPropagation; if (evt.type == "mouseover") { evt.relatedTarget = evt.fromElement; } else if (evt.type =="mouseout") { evt.relatedTarget = evt.toElement; } evt.charCode = (evt.type=="keypress")?evt.keyCode:0; evt.eventPhase = 2;//IE仅工作在冒泡阶段 evt.timeStamp = (new Date()).getTime();//仅将其设为当前时间 } return evt; } fixEvent.preventDefault =function () { this.returnValue = false;//这里的this指向了某个事件对象,而不是fixEvent }; fixEvent.stopPropagation =function () { this.cancelBubble = true; };
fixEvent函数不是单独执行的,它必须有一个事件对象参数,而且只有事件发生时它才被执行!最好的方法是把它整合到addEvent函数的execEventHandles里面
- addEvent.execEventHandles = function (evt) {//遍历所有的事件处理函数并执行
- if (!this.__EventHandles) {return true;}
- evt = fixEvent(evt || window.event);//在这里对其进行标准化操作
- var fns = this.__EventHandles[evt.type];
- for (var i in fns) {
- fns[i].call(this,evt);//并且将其作为事件处理函数的第一个参数
- //这样在事件处理函数内部就可以使用统一的方法访问事件对象了
- }
- };
addEvent.execEventHandles = function (evt) {//遍历所有的事件处理函数并执行 if (!this.__EventHandles) {return true;} evt = fixEvent(evt || window.event);//在这里对其进行标准化操作 var fns = this.__EventHandles[evt.type]; for (var i in fns) { fns[i].call(this,evt);//并且将其作为事件处理函数的第一个参数 //这样在事件处理函数内部就可以使用统一的方法访问事件对象了 } };
Load事件
使用JavaScript操纵DOM,必须等待DOM加载完毕才可以执行代码,但window.onload有个坏处,它非要等到页面中的所有图片及视频加载完毕才会触发load事件。结果就是一些本来应该在打开时隐藏起来的元素,由于网络延迟,在页面打开时仍然会出现,然后又会突然消失,让用户觉得莫名其妙。
大师们想出来的方法:
- function addLoadEvent(fn) {
- var init = function() {
- if (arguments.callee.done) return;
- arguments.callee.done = true;
- fn.apply(document,arguments);
- };
- //注册DOMContentLoaded事件,如果支持的话
- if (document.addEventListener) {
- document.addEventListener("DOMContentLoaded", init, false);
- }
- //但对于Safari,我们需要使用setInterval方法不断检测document.readyState
- //当为loaded或complete的时候表明DOM已经加载完毕
- if (/WebKit/i.test(navigator.userAgent)) {
- var _timer = setInterval(function() {
- if (/loaded|complete/.test(document.readyState)) {
- clearInterval(_timer);
- init();
- }
- },10);
- }
- //对于IE则使用条件注释,并使用script标签的defer属性
- //IE中可以给script标签添加一个defer(延迟)属性,这样,标签中的脚本只有当DOM加载完毕后才执行
- /*@cc_on @*/
- /*@if (@_win32)
- document.write("<script id=\"__ie_onload\" defer=\"defer\" src=\"javascript:void(0)\"><\/script>");
- var script = document.getElementById("__ie_onload");
- script.onreadystatechange = function() {
- if (this.readyState == "complete") {
- init();
- }
- };
- /*@end @*/<
发表评论
-
js获取当前时间
2009-12-01 16:31 14233//取得当前时间 (默认给违约的创建时间) window.o ... -
JavaScript窗体对象
2009-09-03 14:08 980导读: 熟练window对 ... -
弹出窗口window.showModelessDialog参数介绍
2009-09-01 14:14 3590网页对窗口控制已经有很多文章介绍了,但控制对话框的技巧却不是很 ... -
超链接中怎么调用JavaScript
2009-09-01 12:46 4300点击超链接调用 JavaScript 函数,一般人都用: & ... -
Javascript刷新页的方法汇总
2009-08-31 14:13 1029先来看一个简单的例子:下面以三个页面分别命 ... -
一些常用的JavaScript
2009-08-31 10:56 654注册界面(添加界面): <script type=&q ... -
页面常用JavaScript
2009-08-31 08:52 807zhuxinyu 写道1. 禁用backspacke d ...
相关推荐
JavaScript之DOM事件(源代码)JavaScript之DOM事件(源代码)JavaScript之DOM事件(源代码)JavaScript之DOM事件(源代码)JavaScript之DOM事件(源代码)JavaScript之DOM事件(源代码)JavaScript之DOM事件(源...
在DOM部分,书中详细讲解了DOM模型的层次结构,如何通过JavaScript访问和修改HTML元素,以及如何利用DOM事件来响应用户交互。理解DOM节点、属性、事件和选择器是创建动态网页的关键,这使得开发者能够动态加载内容、...
8. **DOM事件委托**:利用事件冒泡或事件捕获机制,可以有效地处理大量元素的事件,提高性能。 9. **DOM性能优化**:理解DOM操作的性能影响,如避免不必要的重绘和回流,使用文档碎片等技巧,能够提升网页性能。 ...
JavaScript dom操作 dom元素查询 示例代码JavaScript dom操作 dom元素查询 示例代码JavaScript dom操作 dom元素查询 示例代码JavaScript dom操作 dom元素查询 示例代码JavaScript dom操作 dom元素查询 示例代码...
5. DOM事件处理:JavaScript通过事件驱动进行交互。事件会在特定的动作(如点击、按键、加载等)发生时被触发,DOM提供了添加和移除事件监听器的接口。学习如何在DOM元素上绑定事件和编写事件处理函数是提高网页交互...
JavaScript+DOM编程艺术是一本深度探讨如何利用JavaScript与DOM(Document Object Model)进行网页动态交互的书籍。DOM是HTML和XML文档的结构化表示,它为网页内容提供了一种易于程序化访问和修改的方式。JavaScript...
8. **DOM事件流**:DOM事件流包括捕获阶段、目标阶段和冒泡阶段。理解这个过程对于有效处理事件至关重要。 9. **事件委托**:利用事件冒泡,可以在父元素上设置监听器处理子元素的事件,减少内存消耗和代码冗余。 ...
JavaScript DOM编程艺术(第2版)是一本深受程序员喜爱的JavaScript技术书籍,专注于讲解如何使用JavaScript与Document Object Model(DOM)进行交互。DOM是Web页面的结构化表示,它允许我们通过编程方式操纵HTML和XML...
根据提供的文件信息,我们可以推断出这是一本关于JavaScript DOM编程技术的书籍——《JavaScript DOM编程艺术(第2版)》。尽管实际书籍内容并未给出,但从标题、描述及部分链接信息来看,这本书主要涉及JavaScript...
《JavaScript DOM编程艺术》是Jeremy Keith所著的一本关于JavaScript和DOM(文档对象模型)编程的经典图书,它不仅阐述了JavaScript和DOM的基本知识,还着重讲解了DOM编程技术背后的思路和原则。本书被赞誉为Web设计...
10. **DOM变更事件**:DOM操作如添加、删除元素时,会触发DOM事件,如`DOMNodeInserted`和`DOMNodeRemoved`,可以利用这些事件进行响应式编程。 通过学习并实践《JavaScript DOM编程艺术》中的源码,开发者能够掌握...
事件是JavaScript编程中不可或缺的一部分,JavaScript DOM编程艺术详细介绍了事件的概念和机制。作者会介绍如何使用事件监听器来捕捉用户的交互行为,并为不同类型的事件(如点击、键盘输入、表单提交等)编写相应的...
Beginning JavaScript with DOM Scripting and Ajax is an essential resource for modern JavaScript programming. This completely updated second edition covers everything you need to know to get up-to-...
在书中,作者会详细介绍如何利用JavaScript与DOM进行交互,这包括选取元素(如通过选择器API或XPath),修改元素属性,以及处理事件。还会探讨如何使用CSS样式和JavaScript结合来实现动态布局和视觉效果。此外,书中...
4. **响应式设计**: 根据窗口大小调整元素布局,利用DOM事件监听窗口尺寸变化。 5. **拖放功能**: 实现元素的拖放操作,涉及事件监听和元素状态的改变。 6. **模板引擎**: 配合模板字符串和DOM操作,动态生成和...
本资源为JavaScript的dom操作的趣味案例,可直接打开查看本资源为JavaScript的dom操作的趣味案例,可直接打开查看本资源为JavaScript的dom操作的趣味案例,可直接打开查看本资源为JavaScript的dom操作的趣味案例,可...
DOM提供了一套API,包括节点操作(如创建、插入、删除节点)、事件处理(如点击、鼠标移动等)、属性访问等。例如,可以使用`appendChild()`方法在元素的末尾添加新子节点,`addEventListener()`来监听和响应用户...
《Javascript+DOM编程艺术(完整版)》是Jeremy Keith所著的一本关于前端开发技术的书籍,专注于Web设计中的JavaScript和DOM编程。本书被认为是前端开发者必读的经典之作,其清晰的文笔、遵循优秀的编程原则和严格的...
DOM Enlightenment可能涵盖了如何通过JavaScript访问和修改DOM节点,包括元素选择(如querySelector和querySelectorAll)、遍历DOM树、添加和删除元素、以及事件处理。此外,还可能涉及到性能优化技巧,如使用文档...
本 书在简洁明快地讲述JavaScript和DOM的基本知识之后,通过几个实例演示了专业水准的网页开发技术,透彻阐述了平稳退化等一批至关重要的 JavaScript编程原则和最佳实践,并全面探讨了HTML5以及jQuery等JavaScript库...