JavaScript事件

1.事件流

1.1事件冒泡

IE的事件流叫做事件冒泡,事件开始时由最具体的元素节点接收,逐步向上传播。




    Event Bubbling Example


    
Click Me

如果你在div设置了一个点击事件,则传播顺序:1.div 2.body 3.html 4.document

1.2 事件捕获

不太具体的节点应该更早的接收事件。在事件达到预期目标之前捕获它。
仍然是上面的例子,事件捕获顺序:1.document 2.html 3.body 4.div

1.3 DOM事件流

DOM事件流分为三个阶段:事件捕获、目标阶段、事件冒泡。


2.事件处理程序

事件是用户或者浏览器自身执行的动作。响应某个事件的函数叫做事件处理程序。

2.1 HTML事件处理程序

通过html的方式实现一个onclick事件


2.2 DOM0级事件处理程序

这也是现在最常用的一种方法。为啥常用?原因一是简单,原因二具有跨浏览器优势。

var btn = document.getElementById("myBtn");
btn.onclick = function () {
    alert("hello");
};
2.3 DOM2级事件处理程序

“DOM2级事件”定义了两个方法,用于处理指定和删除事件处理程序的操作:addEventListener()和removeEventListener()。
所有的DOM节点都包含这两个方法。接收三个参数:要处理的时间名、作为事件处理程序的函数和布尔值。最后这个布尔值是true,表示在捕获节点调用时间处理程序;如果是false,表示在冒泡阶段调用时间处理程序。

var btn = document.getElementById("myBtn");
btn.addEventListener("click", function(){
    alert(this.id);
}, false);

btn.addEventListener("click", function(){
    alert("Hello world!");
}, false);
2.4 IE事件处理程序

IE实现了DOM中类似的两个方法:attachEvent()和detachEvent()。这两个方法接收相同的两个参数:事件处理程序名称与时间处理程序函数。IE8及更早的版本只支持事件冒泡,所以通过attachEvent()添加的时间处理程序都会被添加到冒泡阶段。

var btn = document.getElementById("myBtn");
btn.attachEvent("onclick", function(){
    alert("Clicked");
});
btn.attachEvent("onclick", function(){
    alert("Hello world!");
});
2.5 跨浏览器的事件处理程序

要保证处理事件的带啊能在大多数浏览器下一致的执行,只需要关注冒泡阶段。
第一个要创建的放大是addHandler(),它的作用是视情况而定分别使用DOM0级方法、DOM2级方法或IE方法来添加事件。addHandle()接受三个参数:要操作的元素、事件名称和事件处理程序函数。

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

3.事件对象

在触发DOM上的某个事件时,会产生一个event对象,这个对象中包含素有时间有关的信息。事件的元素、事件的类型及其他相关信息。例如,鼠标点击导致的事件,可以获取到鼠标点击的位置;键盘操作导致的事件,会包含与按下的键有关的信息。

3.1 DOM中的时间对象

兼容DOM的浏览器会将一个event对象传入到时间处理程序中。无论指定时间处理程序时使用什么方法,都会传入event对象。

var btn = document.getElementById("myBtn");
btn.onclick = function(event){ 
    alert(event.type);          //"click"
};

btn.addEventListener("click", function(event){
    alert(event.type);          //"click"
}, false);

关于Event对象包含的属性与方法

属性/方法 类型 读/写 说明
bubbles boolean 只读 表明时间是否冒泡
cancelable boolean 只读 表名是否可以取消事件默认行为
currentTarget Element 只读 其事件处理程序当前正在处理事件的那个元素
defaultPrevented boolean 只读 为true表示已经调用了preventDefault()
detail Integer 只读 与事件相关的细节信息
eventPhase Integer 只读 调用时间处理程序的阶段,1表示捕获阶段,2表示处于目标,3表示冒泡阶段
preventDefault() Function 只读 取消事件默认行为
stopImmediatePropagation() Function 只读 取消事件的进一步捕获或冒泡,同时阻止任何事件处理程序被调用
stopPropagation() Function 只读 取消事件的进一步捕获或冒泡,如果bubbles为true,则可以使用这个方法
target Element 只读 事件的目标
trusted boolean 只读 为true表示事件是浏览器生成。false表示事件使用开发人员通过JS创建
type String 只读 被触发事件的类型
view AbstractView 只读 与事件关联的抽象视图。等同于发生事件的window对象

在对象处理程序内部,对象this扥估currentTarget的值。

var btn = document.getElementById("myBtn");
btn.onclick = function(event) {
    alert(event.currentTarget === this);    //true
    alert(event.target === this);           //true
};

4.事件类型

事件类型分类:UI事件、焦点事件、鼠标事件、滚轮事件、文本事件、键盘事件、合成事件、变动事件。

4.1 UI事件

1.load事件:JS中最常用的就是load事件。当页面加载后就会触发window上的load事件。如何定义onload事件呢?可以看下demo

第一种,JS声明
EventUtil.addHandler(window, "load", function(event){
   alert("Loaded"); 
});

第二种,标签属性

2.unload事件:文档被完全卸载后触发。只要用户从一个页面切换到另一个页面就会触发unload。利用这个事件最多的情况是清除引用,避免内存泄露。

第一种,JS声明
EventUtil.addHandler(window, "unload", function(event){
        alert("Unloaded");
});

第二种,标签属性

3.resize事件:当浏览器窗口被调整到一个新的高度或宽度时,就会触发resize事件。注意resize事件会频繁被触发,所以在尽量不要书写大量运算逻辑,会导致浏览器变慢。

第一种,JS声明
EventUtil.addHandler(window, "resize", function(event){
        alert("Resized");
});

第二种,标签属性

4.scroll事件:当用户滚动带滚动条的元素内容时触发。在window对象上发生的,表示页面中响应元素的变化。跟resize事件类似,scroll会频发触发。所以在尽量不要书写大量运算逻辑,会导致浏览器变慢

EventUtil.addHandler(window, "scroll", function(event){
    if (document.compatMode == "CSS1Compat"){
        alert(document.documentElement.scrollTop);
    } else {
        alert(document.body.scrollTop);
    }
});
4.2 焦点事件(这里就不写demo了,会对事件做一个详细的分析)
  • blur:在元素市区焦点时触发。这个事件不会冒泡(但是可以捕获阶段监听到)
  • focus:在元素获得焦点时触发。这个事件不会冒泡(但是可以捕获阶段监听到)
  • focusion:在元素获得焦点时触发。这个事件会冒泡
  • focusout:在元素失去焦点时触发。这个事件会冒泡
4.3 滚动与滚轮事件
  • click:在用户单击主鼠标按钮或者回车键触发
  • dblclick:在用户双击主鼠标按钮时触发
  • mousedown:在用户按下任意鼠标按钮时触发。
  • mouseenter:鼠标光标从元素外部首次移动到元素范围内触发。(IE、Firefox 9+和Opera支持)
  • mouseleave:在位于元素上方的鼠标光标移动到元素范围之外时候触发。(IE、Firefox 9+和Opera支持)
  • mousemove:当鼠标指针在元素内部移动时重复触发。
  • mouseout:在鼠标指针位于一个元素上方,然后用户将其移入另一个元素时触发。
  • mouseover:在鼠标指针位于一个元素外部,然后用户将其移入另一个元素边界之内时触发。
  • mouseup:在用户释放鼠标按钮时触发。

1.客户区坐标位置(整个浏览器去掉工具栏等其他辅助工具的位置)

var div = document.getElementById("MyDiv");
EventUtil.addHandler(div, "click", function(event){
    event = EventUtil.getEvent(event);
    alert("Client coordinates: " + event.clientX + "," + event.clientY);
});

2.页面坐标位置

var div = document.getElementById("MyDiv");
EventUtil.addHandler(div, "click", function(event){
    event = EventUtil.getEvent(event);
    alert("Page coordinates: " + event.pageX + "," + event.pageY);
});

3.屏幕坐标位置(获取的是整个用户操作系统界面的坐标)

var div = document.getElementById("myDiv");
EventUtil.addHandler(div, "click", function(event){
    event = EventUtil.getEvent(event);
    alert("Screen coordinates: " + event.screenX + "," + event.screenY);
});

4.修改键
修改键就是Shift、Ctrl、Alt,这些经常被用来修改鼠标性情。因此DOM规定了四个属性,来修改这些按键的状态:shiftKey、ctrlKey、altKey和metaKey。这些属性都是布尔值,如果这些按键按下了则为true,否则为false。

var div = document.getElementById("myDiv");
EventUtil.addHandler(div, "click", function(event){
    event = EventUtil.getEvent(event);
    var keys = new Array();
    if (event.shiftKey){
        keys.push("shift");
}
    if (event.ctrlKey){
        keys.push("ctrl");
}
    if (event.altKey){
        keys.push("alt");
}
    if (event.metaKey){
        keys.push("meta");
}
    alert("Keys: " + keys.join(","));
});
4.4 键盘与文本事件
  • keydown:当用户按下键盘上任意键时触发。按住不放,重复执行此事件
  • keypress:当用户按下键盘上的字符键时触发。按住不放,重复执行此事件
  • keyup:当用户释放按键时触发

1.键码
键盘上每个按键都有一个keyCode属性用于标识按键的。

var textbox = document.getElementById("myText");
EventUtil.addHandler(textbox, "keyup", function(event){
    event = EventUtil.getEvent(event);
    alert(event.keyCode);
}); 

2.字符编码
浏览器event对象都支持一个charCode属性,这个属性只有在发生keypress事件才有值,而且这个值是安县哪个键锁代表的字符的ASCII编码。通常用来检验浏览器字符集。

3.textInput事件
用户在可编辑区域中输入字符时,就会触发这个事件。

var textbox = document.getElementById("myText");
EventUtil.addHandler(textbox, "textInput", function(event){ event = EventUtil.getEvent(event);
alert(event.data);
}); 

5.内存与性能

5.1 事件委托

对事件处理程序过多的时候,就可以通过委托的方式去解决。事件委托利用了事件冒泡。指定一个事件处理程序,就可以管理一类型所有的事件。




function getEvent(){
    var list = document.getElementById("myLinks");
    EventUtil.addHandler(list, "click", function(event){
        event = EventUtil.getEvent(event);
        var target = EventUtil.getTarget(event);
    }
}

5.2 移除事件处理程序

每当事件处理程序指定元素时,运行中的浏览器代码与支持页面交互的JS代码会建立一个链接。这种链接越多,页面执行越慢。可以两种方式规避这个问题,可以采用事件委托技术限制建立连接数。另外,在不需要的时候移除事件处理程序。

btn.onclick = funciotn(){
    //执行某些操作
    btn.onclick = null; //移除事件处理程序
    document.getElementById("myDiv").innerHTML = "Processing...";
};

你可能感兴趣的:(JavaScript事件)