JS事件

js与HTML之间的交互通过事件实现的。
事件流:描述从页面接受事件的顺序
  ● IE事件流——事件冒泡流 从文档中嵌套层次最深的那个节点开始接受 (常用)
  ● Netscape Communicator的事件流——事件捕获流

1。DOM事件 规定的事件流包括3各阶段:时间捕获阶段,处于目标阶段和事件冒泡阶段

DOM2级事件规范要求捕获阶段不会涉及到事件目标,但在IE9,Safari,Chrome,Firefox和Opera 9.5中都会在捕获阶段触发事件对象上的事件,结果,有两次机会在目标对象上操作事件


2. DOM0级事件处理程序
就是将一个函数赋值给一个事件处理程序属性(如click load mouseover 就是事件处理程序)
DOM0级对每个事件只支持一个事件处理程序

<input type="button" value="click me" onclick="alert(this.value);">

 

3.DOM2级事件处理程序

/* 
*DOM2级事件 定义了两个方法,用于处理指定和删除事件处理程序: addEventListener()和removeEventListener()
接受3个参数:要处理的事件名,事件处理程序的函数,一个布尔值
布尔值为true 表示在捕获阶段调用事件处理程序
布尔值为false 表示在冒泡阶段调用事件处理程序(一般是false)
*/
var btn=document.getElementById("myBtn");
btn.addEventListener("click",function(){
alert(this.id);
},false);
// DOM2级方法添加事件处理程序好处:可以添加多个事件处理程序 触发是按代码先后顺序
// 通过addEventListener()添加的事件处理程序只能使用removeEventlistener()来移除
// 注意:通过addEventlistener()添加的匿名函数无法移除
// 正确的代码 把匿名函数赋给一个变量 通过变量指定
var btn=document.getElementById('myBtn');
var handler=function(){
alert(this.id);
};
btn.addEventListener("click",handler,false);
// 这里省略其他代码
btn.removeEventListener("click",handler,false);//有效
大多数情况,都是将事件处理程序添加到事件冒泡阶段(第三个参数为false)

// 跨浏览器的事件处理程序 创建一个EventUtil对象
/* addHandler() 与removeHandler()
接受3个参数:要操作的元素。事件名称,和事件处理程序函数

*/
var EventUtil = {
addHandler: function (element, type, handler) {
if (element.addEventListener) {
element.addEventListenr(type, handler, false);
} else if (element.attachEvent) {
element.attachEvent("on" + type, handler);
} else {
element["on" + type] = handler;
}
},
removeHandler: function (element, type, handler) {
if (element.addEventListener) {
element.removeEventListener(type, handler, false);
} else if (element.attachEvent) {
element.detachEvent("on" + type, handler);
} else {
element["on" + type] = null;
}
}
};

var btn=document.getElementById('myBtn');
var handler=function(){
alert('clicked');
};
EventUtil.addHandler(btn,"click",handler);
// 这里省略了其他代码
EventUtil.removeHandler(btn,"click",handler);

 


4.事件对象
在触发DOM上的某个事件时,会产生一个事件对象event。
这个对象包含所有与事件有关的信息
event对象包含的属性和方法(均为只读)
    属性/方法 类型 说明
    ● bubbles Boolean 表明事件是否冒泡
    ● cancleable Boolean 是否可以取消事件的默认行为
    ● currentTarget element 指向当前的那个元素
    ● dedaultPrevented Boolean 为true 表示已调用preventDefault()
    ● datail Integer(整数) 事件相关的细节信息
    ● eventPhase integer 事件处理程序的阶段:1表示捕获阶段 2 处于目标阶段 3 表示事件冒泡阶段
    ● preventDefault() function 取消事件的默认行为 cancleable为true可以调用它
    ● stopImmediatePropagation() 取消事件进一步捕获和冒泡,同时阻止事件处理程序被调用
    ● stopPropagation() 取消事件进一步捕获和冒泡 当bubbles为true调用它
    ● target element 事件的目标
    ● trusted boolean true表示浏览器生成
    ● type String 被触发的事件类型
    ● view AbstractView
    在事件处理程序函数内部,对象this始终等于 currentTarget的值

// 避免触发注册在document.body上的事件处理程序
var btn=document.getElementById("myBtn");
btn.onclick=function(event){
alert('clicked');
event.stopPropagation();
};
document.body.onclick=function(event){
// alert("body clicked");
alert(event.eventPhase);//3 处于事件冒泡阶段
}

只有在事件处理程序执行期间,event对象才存在,一旦事件处理程序执行完毕,event对象就会被销毁

在IE中,event参数是未定义的(undefined),因此就会返回window.event


5 事件类型
DOM3规定了一下几类事件:
  1. UI(user interface 用户界面)事件:用户与页面元素交互时触发
    load 当页面加载完成(包括所有图像,js文件,css文件等外部资源)触发window上面的load事件
  2. 焦点事件
  3. 鼠标事件
  4. 滚轮事件
  5. 键盘事件
  6. 合成事件:当为IME(input method editor)输入字符时触发
  7. 受动(mutation)事件:当底层DOM结构发生改变时触发

EventUtil.addHandler(window,"load",function(event){
alert('load');
});


  5.1 根据DOM2的规范:应该在document而非window上面触发load事件,当时所有浏览器都在window上实现了load,来保证向后兼容
  5.2 unload事件 只要用户从一个界面切换到另一个界面,就会发生unload事件-——unload事件主要用来清楚引用,以避免内存泄漏(注意 其实这个事件是在body上触发的,不是window上,但为了向后兼容)

window.addEventListener('unload',function(event){
alert('unload');
},false);

 

  5.3 resize事件
    当浏览器窗口大小发生改变时发生resize事件。(不要再这个事件中加入大计算量的代码 )
  5.4 scroll事件 滚动

    焦点事件:
    blur 元素 失去焦点时触发
    focus 元素活得焦点
    鼠标与滚动事件
    click dblclick (mousedown按下鼠标按钮时触发 mouseup)
    鼠标滚轮事件 mousewheel
    在event中clientX clientY储存点击的位置信息
    在没有滚动的情况下 pageX的值=clientX pageY的值=clientY

    屏幕坐标位置 ——是相对于电脑屏幕的 screenX和screenY

event.keyCode ——键盘操作所对应ASCII码

setTimeout(function(){
//在此添加事件处理程序
},0);//表示在当前js处理完成后立即运行这个函数

// hashchange url参数列表发生变化时触发 在ajax中用来保存状态或导航信息
window.addEventListener('hashchange',function(event){
alert("old URL="+event.oldURL+"; new URL="+event.newURL);
},false);

 

6. 事件委托—— 解决事件处理程序过多的问题,利用事件冒泡
只需在DOM树中尽量最高的层次上添加一个事件处理程序(而不用为树下每一个子元素添加事件处理程序)
每个函数都是对象,都会占用内存,内存中对象越多,性能就会越差

事件委托的优点:
  ● document对象很快就能访问到
  ● 在页面中设置事件处理程序所需的时间少
  ● 整个页面占用的内存小
/*
内存优化——事件委托

<ul id="mylinks">
  <li id="goSomewhere"> go goSomewhere</li>
  <li id="doSomething">doSomething</li>
  <li id="sayHI">sayHI</li>
</ul>

对于ul元素每一项添加点击事件

*/
(function () {
var list = document.getElementById('mylinks');
list.addEventlistener('click', function (event) {
  switch (event.id) {
    case "goSomewhere":
        location.href = 'http://www.wrox.com';
        break;
    case "doSomething":
        document.title = "i change the document's title";
        break;
    case "sayHI":
        alert('hi');
    break;
  }
}, false);
})();

 


6.1 移除事件处理程序: 两种情况
  ● 删除了元素,但元素相关的事件处理程序还一直在内存中, 解除引用 设置为null
  ● 在页面被卸载之前没有清理干净事件处理程序,他就会滞留在内存中,尤其实在两个界面来回切换时(或者刷新时),内存中的对象数目就会增加


7.模拟事件
用js在任意时刻触发特定的事件,在测试web应用程序时极其有用
DOM中事件模拟 在document上创建 createEvent () 接受一个参数 需要创建事件的字符串类型:
  ● UIevents 一般的UI事件 鼠标 键盘事件继承自UI事件 DOM3中UIevent
  ● MouseEvents 鼠标事件 DOM3级中时MouseEvent
  ● MutationEvents一般的DOM变动事件 DOM3中时MutationEvent
  ● HTMLevents 一般的HTML事件

// 模拟鼠标事件
var btn=document.getElementById('myBtn');
// 创建事件对象
var event=document.createEvent('MouseEvents');
// 初始化事件对象
event.initMouseEvent("click",true,true,document.defaultView,0,0,0,0,0,false,false,false,false,0,null);
// 触发事件
btn.dispatchEvent(event);

 

posted @ 2017-11-26 14:54  sundjly  阅读(158)  评论(0编辑  收藏  举报