微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

JavaScript高级程序设计—第十三章事件

1.事件流:事件流是指在浏览器中接受事件的顺序,在IE浏览器中支持的是事件冒泡机制(旧版本仅支持事件冒泡),即事件是由最具体的元素(目标元素)逐步向上传递到不具体的元素(文档)。另一个事件流机制叫事件捕获,即事件由不具体的元素向下传播到具体的元素,具体的节点最后接收到事件。目前基本新版本浏览器都支持事件冒泡和事件捕获,认情况下事件会按冒泡机制执行。

ottonBox = document.querySelector(".button-Box");        // botton的父级元素
  button.addEventListener("click",function(){                    // 绑定事件时认值为false(事件冒泡)
    console.log('aaa')
  }) 
  bottonBox.addEventListener("click",function(){
    console.log('bbb')
  }) 
  document.body.addEventListener("click",function(){            // 绑定事件是设置参数为true时为事件捕获
    console.log('ccc')
  },true) 

因此上面代码在控制台打印结果为ccc aaa bbb,由于绑定在body上的click事件指定在捕获阶段执行,因此最开始事件捕获时立刻执行body上的click事件,而绑定在buttonBox和button上的click事件指定在冒泡阶段执行,因此冒泡时先执行了button上的click事件,当冒泡到buttonBox时再执行buttonBox上的click事件。
需要注意的是,在旧版本的IE浏览器中只支持事件冒泡机制,因此为了保证兼容性我们常常指定事件在冒泡阶段执行。

2.事件绑定函数和事件移除函数:addEventListener()和removeEventListener()。addEventListener()函数接受三个参数,第一个参数指定事件类型,第二个参数指定处理事件到回调函数,第三个参数指定事件的执行机制(认值为false冒泡执行)。

3.事件绑定函数的兼容性问题,在旧版本的IE浏览器中绑定事件函数为attachEvent(),移除事件函数为detachEvent(),由于低版本IE只支持事件冒泡,因此这两个函数只接受两个参数,第一个参数为事件类型,第二个参数为事件处理的回调函数。为了保证兼容性问题,我们常常需要根据不同的浏览器使用不同的函数

4.DOM事件对象event:在绑定事件时,兼容DOM的浏览器会将一个事件对象传入到事件处理的回调函数中,event对象中包含了多个与事件相关的只读属性方法

默认行为
currentTarget           // 事件处理程序当前正在处理事件的哪个元素
detail                // 与事件相关的信息
evnetPhase             // 事件处理的阶段,1为捕获阶段,2表示处于目标,3表示冒泡阶段
preventDefault           // 阻止事件的认行为,比如a链接跳转
stopPropagation          // 取消事件的进一步捕获或冒泡,如果bubbles为true则可以使用此方法
target                // 事件目标(作用的元素)

5.IE事件对象,旧版本的IE浏览器的事件对象和DOM事件对象有较大的差别,在使用DOM0级方式添加事件处理程序时,event对象作为window对象的一个属性存在,下面是IE事件对象中的属性方法

默认值为false,设置为true时可以阻止事件继续冒泡(与DOM中的stopPropagation()方法作用相同)
returnValue             // 读/写,认值为true,将其设置为false会取消事件的认行为()与DOM中的preventDefault()方法作用相同
srcElement              // 只读,yuDOM中的target属性相同
type                    // 只读,触发事件类型

为了实现跨浏览器的事件对象,我们需要针对不同的浏览器使用不同的方法

代码
  },// 获取事件对象
  getEvent: function(event) {
    return event ? event : window.event;
  },// 获取事件作用的目标元素
  getTarget: function(event) {
    return event.target || event.srcElement;
  },// 阻止元素的认行为
  preventDefault: function(event) {
    if(event.preventDefault) {
      event.preventDefault();
    }
    else {
      event.returnValue = false;
    }
  },// 阻止事件继续冒泡
  stopPropagation: function(event) {
    if(event.stopPropagation) {
      event.stopPropagation();
    }
    else {
      event.cancelBubble = true;
    }
  }
};

6.事件类型:事件类型包含了UI事件、鼠标事件、滚轮事件、键盘事件、焦点事件等一系类的事件类型,这里只介绍常用的几种事件
UI事件:
(a)load事件:当资源(页面图片、框架)加载完成后触发的事件
(b)unload事件:与load事件向对象,当页面、框架等资源卸载后触发的事件
(c)error事件:当资源加载出错时触发的事件
(d)scroll事件:当页面发生滚动时触发的事件,注意与鼠标的滚轮事件区分开
(e)resize:当浏览器窗口大小发生改变时触发的事件

后执行相应的代码
  event = EventUtil.getEvent(event);
  console.log(EventUtil.getTarget(event).src);
})
document.body.appendChild(image);
image.src = "1.png"

// scroll页面滚动事件
EventUtil.addHandler(window,"scroll",function(event){
if(document.compatMode == "CSS1Compat") { // 使用html元素的scrollTop和scrollLeft来获取页面滚动的距离
console.log(document.documentElement.scrollTop); // 标准模式下使用document.documentElement.scrollTop获取
}
else {
console.log(document.body.scrollTop) // 混杂模式下使用document.body.scrollTop来获取
}
})

鼠标与滚轮事件:
(a)click事件:鼠标单击时触发
(b)dbclick事件:双击鼠标时触发
(c)mousedown:按下鼠标任意键时触发
(d)mouseenter:光标从元素外部移入时触发
(e)mouseleave:当光标从元素上移出时触发
(f)mouSEOut:光标位于一个元素上方,然后用户将其移入另一个元素时触发,另一个元素可能在当前元素内部,也可能在当前元素外部
(g)mouSEOver:光标位于一个元素外部,然后用户将其移入另一个元素时触发
(h)mouseup:用户释放鼠标时触发,与mousedown事件相对
注意这里有几个事件是相互关联的,比如一次click事件是有一次mousedown事件和mouseup事件组成的,一次dblclick事件是由两次click事件组成的,下面代码中,当点击button按钮时,会一次触发mousedown、mouseup、click事件。

滚轮式事件wheel:当鼠标滚轮滚动时会触发滚轮事件,同时可以通过wheelDelta属性来判断滚动的方向,当正向滚动时wheelDelta是+120的倍数;当负向滚动时,wheelDelta是-120的倍数。不过此事件在浏览器间存在兼容性问题,在fireFox浏览器上,不支持这个事件,但是支持DOMMouseScroll事件,因此为了兼容不同的浏览器,我们需要针对不同的浏览器执行不同的代码

键盘事件:
(a)keydown:按下键盘上的任意键时触发。
(b)keyup:释放键盘上的按键时触发。
(c)keypress:按下键盘上的字符键时触发。
键码keyCode和和字符编码charCode:
当发生keydown和keyup事件时,event对象会包含一个keyCode属性,此属性的值时键盘上所有按键对应的键码,数字和字母则用其对应的ASCII码表示。当keypress事件发生时,event对象会包含一个charCode属性,该属性的值为按下键所对应的ASCII码。
不过需要注意的是,charCode属性也存在兼容性问题,在IE8及之前的版本和opera中,统一在keyCode中保存按键对应的ASCII码,因此使用此属性时需要编写兼容性代码

代码

getCharCode:function(event) {
if(typeif event.charCode == "number") {
return event.charCode;
}
else {
return event.keyCode;
}
}
}
EventUtil.addHandler(textBox,"keypress",function(event) {
event = EventUtil.getEvent(event);
console.log(EventUtil.getCharCode(event));
})

7.事件委托:事件委托是指给某个元素绑定事件时,不直接绑定在该元素上,而是绑定在其父级元素上面,这样只需要在父级元素上绑定一次事件就可以为所有的子元素绑定上事件了。

if(target.nodeName.toLowerCase() == "li") {        // 根据子元素的nodeName执行相应的代码,也可以根据其他属性比如id、className等
console.log("aaa")
}
})

使用事件委托还有一个好处,在移除事件的时候也只需要移除一次事件。我们知道将一段程序指定给页面中的一个元素时,元素和代码之间就会简历一种连接(就是程序对dom元素的引用),这种连接越多,占用的浏览器内存相应的也就越多,执行速度也会相应变慢,而且如果没有及时的清除引用还可能会造成内存泄漏等后果。

移除事件:当页面中某个元素被移除时,相应的其绑定的事件也应该被移除,但是很多时候浏览器的垃圾回收机制并不会自动移除绑定的事件,因此为了避免内存泄漏,这个操作需要我们手动完成。移除事件代码很简单,只需要为元素的事件赋值为null即可(例如element.click = null;)。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐