【JavaScript】事件

所谓事件,就是文档或浏览器窗口中发生的一些特定的交互瞬间

一、事件流

在页面上,单击某个元素的同时,也单击了它的包含容器。事件流就是描述的从页面中接收事件的顺序。IE是事件冒泡流,Netscape是事件捕获流。

事件冒泡:事件开始时,由最具体的元素接收,然后逐级向上传播到较为不具体的节点;(所有现代浏览器都支持事件冒泡)

事件捕获:不太具体的节点最早接收到事件,最具体的节点最后接收到事件。(老版本浏览器不支持)

DOM事件流

DOM2级事件规定的事件流包括三个阶段:1、事件不惑阶段;2、处于目标阶段;3、事件冒泡阶段

DOM事件流中,实际的目标在捕获阶段不会接收到时间

二、事件处理程序

事件就是用户或浏览器自身执行的某种动作,如click/load/mousedown,这些都是事件的名字。

事件处理程序:是响应某个事件的函数

为事件指定事件处理函数的方法有3种:

1、HTML事件处理程序

某个元素支持的每种事件,都可以在元素内部,使用与事件处理程序同名的HTML属性来指定。这个属性的值是能够执行的JavaScript代码,既可以包含要执行的具体动作,也可以调用在页面其他地方定义的脚本。

<input type="button" value="点我有惊喜" onclick="alert(‘hello,vicky!‘)" />

缺点:

1、存在时差,用户可能会在HTML元素加载完就触发相应事件,而这时相应的事件处理程序还没有加载完,就会报错

2、使得HTML代码和JavaScript代码耦合,所以不推荐使用!

2、DOM0级事件处理程序

每个元素都有自己的事件处理程序属性,这些属性通常全部小写,将这种属性的值设置为一个函数,就可以指定事件处理程序。

var btn = document.getElementById("btn");//取得一个要操作对象的引用
btn.onclick = function () {
    alert("hello vicky!");
}

3、DOM2级事件处理程序

DOM2级事件定义了两个方法:addEventListener( ) removeEventListener( ),都接受三个参数,要处理的事件名,事件处理函数,一个布尔值(true表示在捕获阶段调用事件处理程序,false表示在冒泡阶段)

var btn = document.getElementById("btn");
btn.addEventListener("click", function (){
    alert("hello vicky!");
},false);
btn.addEventListener("click",function () {
    alert("hello jay!")
}, false);//可以添加多个事件处理程序,且按照其添加的顺序触发

通过addEventListener()添加的事件处理程序只能通过 removeEventListener()来移出。事件处理程序是在其依附的元素的作用域中运行

4、IE事件处理程序

IE实现了与DOM中类似的两个方法:attachEvent()和detachEvent()。事件处理程序在全局作用域中运行,添加的事件处理程序都会被添加到冒泡阶段

var btn = document.getElementById("btn");
btn.attachEvent("onclick",function(){
    alert("hello vicky!");
});
btn.attachEvent("onclick",function () {
    alert("hello jay!");
});//添加多个事件处理程序,以添加顺序的相反顺序执行

5、跨浏览器的事件处理程序

var EventUtil = {
    //添加事件处理程序
    addHandler: function (element,type,handler) {
        if (element.addEventListener) {
            element.addEventListener(type,handler,false);//DOM2级
        } else if (element.attachEvent) {
            element.attachEvent("on" + tye,handler);//IE的方法
        } else {
            element["on" + tyle] = handler;//DOM0级
        }
    },
    //取消事件处理程序
    removeHandler: function (element,type,handler) {
        if (element.removeEventListener) {
            element.removeEventListener(type,handler,false);
        } else if (element.detachEvent) {
            element.detachEvent("on" + tye,handler);
        } else {
            element["on" + tyle] = null;
        }
    }
}

三、事件对象

在出发DOM上的某个事件时,会产生要给事件对象event

1、DOM中的事件对象

兼容DOM的浏览器会将一个event对象传入到事件处理程序中。event对象包含于创建它的特定事件有关的属性和方法。

//属性
bubbles:Boolean //表明事件是否冒泡
cancelable:Boolean //表明是否可以取消事件的默认行为
currentTarget:Element //事件处理程序当前正在处理事件的那个元素
defaultPrevented:Boolean //是否调用了preventDefault()
detail:Integer //细节信息
eventPhase: Integer //1,捕获阶段;2,处于目标阶段;3,冒泡阶段
target:Element //事件的目标
trusted:Boolean //是否为浏览器生成
type:Sting //被触发事件的类型

//方法
preventDefault()  //取消事件的默认行为
stopImmediatePropagation() //取消事件的进一步捕获或冒泡,同时阻止任何事件处理程序被调用
stopPropagation() //取消事件的进一步捕获或冒泡。

在事件处理程序内部,对象this始终等于currentTarget的值,target则只包含事件的实际目标

2、IE中的事件对象

不同之处:

1、event对象作为window对象的一个属性存在

2、事件的目标 window.event.srcElement

3、returnValue=false相当于preventDefault()

3、跨浏览器的事件对象

var EventUtil = {
    //获取事件对象
    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.cancleBubble = true;
        }
    }
}

四、事件类型

1、UI事件

UI事件:指的是那些不一定与用户操作有关的事件。主要有:

load事件:页面完全加载后再window上面触发

unload事件:页面完全卸载后在window上触发

abort事件:用户停止下载过程时,如果嵌入的内容还没加载完在object元素上面触发

error事件:发生错误时触发

select事件:用户选择文本框时触发

resize事件:窗口或框架的大小变化时触发

scroll事件:用户滚动带滚动条的元素中的内容时触发

(1)load事件

当页面完全加载后,就会触发window上面的load事件

1)可以为图像设置load事件。

注意:在创建新的img元素时,要在指定其src属性之前先指定事件。新图像元素不一定要从添加到文档后才开始下载,只要设置了src属性就会开始下载。

2)为script元素指定事件处理程序

注意:与图像不同,只有在设置了script元素的src属性并将该元素添加到文档后,才会开始下载JavaScript文件,即指定src属性和指定事件处理程序的先后顺序不重要。

(2)unload事件

在文档被完全卸载后触发,只要用户从一个页面切换到另一个页面,就会发生unload事件。

(3)resize事件

当浏览器窗口被调整到一个新的高度或宽度时,就会触发resize事件

注意:不要在这个事件的处理程序中加入计算量大的代码,因为这些代码很有可能会被频繁执行,从而导致浏览器反应明显变慢。当然,这个缺点也是有办法来解决的,那就是函数节流 ,详情请见之前博客【JavaScript】函数节流

2、焦点事件

blur:在元素失去焦点时触发

focus:在元素获得焦点时触发

这两个事件都不冒泡,所有浏览器都支持它们

3、鼠标与滚轮事件

(1)鼠标事件

click:单击主鼠标或者按下回车键触发

dbclick:双击主鼠标时触发

mousedown:用户按下了任意鼠标按钮时触发

mouseenter:在鼠标光标从元素外部首次移动到元素范围之内时触发。此事件不冒泡,且光标移动到后代元素上不触发

mouseleave:位于元素上的光标移动到元素范围之外时触发

mouseover:鼠标指针在元素内部移动时触发

mouseout:鼠标指针由一个元素移到另一个元素上时触发

mouseup:释放鼠标按钮时触发

//鼠标事件触发顺序
(1)mousedown
(2)mouseup
(3)click
(4)mousedown
(5)mouseup
(6)dbclick

1)位置属性:

clientX,clientY:到浏览器视口区的左边和上边的值

screenX,screenY:到显示屏幕左边和上边的值

offsetX,offsetY:到元素左边和上边的值

2)修改键

shiftKey,ctrlKey,altKey,metaKey.

//打印出用户按下的修改键
        var text = document.getElementById("text");
        EventUtil.addHandler(text,"keydown",function (event) {
            var event = EventUtil.getEvent(event);
            var keys = new Array();
            if (event.shiftKey) {
                keys.push("shift")
            }

            if (event.ctrlKey) {
                keys.push("ctrl");
            }
            console.log(keys);
        }) ;

3)相关元素

发生mouseover和mouseout事件时,还会涉及更多的元素。这两个事件都会涉及把鼠标指针从一个元素的编辑之内移动到另一个元素的边界之内

//获取相关元素
    getRelatedTarget: function (event) {
        if (event.relatedTarget) {//DOM
            return event.relatedTarget;
        } else if (event.toElement) {//mouseout时IE的toElement保存相关元素
            return event.toElement;
        } else if (event.fromElement) {//mouseover时IE的fromElement保存相关元素
            return event.fromElement;
        } else {
            return null;
        }
    }

4)鼠标按钮

event对象存在一个button属性,其值有3种:0表示主鼠标按钮,1表示中间的鼠标按钮,2表示次鼠标按钮

(2)鼠标滚轮事件

将mousewheel事件处理程序指定给页面中的任何元素或document对象,即可处理鼠标滚轮交互操作

使用鼠标事件应注意的问题:

(1)使用click事件执行代码

(2)不要使用onmouseover向用户显示新的选项。原因是 屏幕阅读器中,无法触发mousedown和mouseover事件

(3)不要使用dbclick执行重要的操作。因为键盘无法触发这个事件

4、键盘事件

keydown:用户按下键盘上的任意键时触发

keypress:用户按下键盘上的字符键时触发

keyup:用户释放键盘上的键时触发

textInput:在文本插入文本框之前触发

(1)键码

在发生keydown和keyup事件时,event对象的keyCode属性中会包含一个代码,与键盘上一个特定的键对应。

(2)字符编码

发生keypress事件意味着按下的键会影响到屏幕中文本的显示。

charCode属性:只有在发生keypress事件时才包含值,而且值是ASCII编码。要想跨浏览器取得字符编码,必须首先检测charCode属性是否可用,如果不可用则使用keyCode

//获取charCode
    getCharCode: function (event) {
        if (typeof event.charCode == "number") {
            return event.charCode;
        } else {
            return event.keyCode;
        }
    }

(3)textInput事件

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

textInput事件的event对象中包含一个data属性,这个属性的值就是用户输入的字符(不是编码)。

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

5、HTML5事件

(1)contexmenu事件

contextmenu事件表示何时应该显示上下文菜单,以便开发人员取消默认的上下文菜单而提供自定义的菜单

//contextmenu事件
    EventUtil.addHandler(window,"load",function (event) {
        var div = document.getElementById("myDiv");
        EventUtil.addHandler(div, "contextmenu", function (event) {
            event = EventUtil.getEvent(event);
            EventUtil.preventDefault(event);
            var menu = div.nextElementSibling;
            menu.style.left = event.clientX + "px";
            menu.style.right = event.clientY + "px";
            menu.style.visibility = "visible";
        });
        EventUtil.addHandler(document, "click", function (event) {
            document.getElementById("myMenu").style.visibility = "hidden";
        })
    });

右键出现自定义的上下文信息

(2)readystatechange事件

readystatechange事件的目的是提供与文档或元素的加载状态有关的信息

可能的状态有5种:

uninitialized(未初始化):对象存在但尚未初始化

loading(正在加载):对象正在加载数据

loaded(加载完毕):对象加载数据完成

interactive(交互):可以操作对象了,但还没有完全加载

complete(完成):对象已经加载完毕

并非所有对象都会经历readyState的这几个阶段

栗子:

//readystatechange事件,确定外部js是否加载完毕
    EventUtil.addHandler(window, "load", function () {
        var script = document.createElement("script");
        EventUtil.addHandler(script, "readystatechange", function (event) {
            var event = EventUtil.getEvent(event);
            var target = event.getTarget(event);
            if (target.readyState == "loaded" || target.readyState == "complete") {
                EventUtil.removeHandler(target, "readystatechange", arguments.callee);
                alert("event.js is loaded");
            }
        });
        script.src = "test.js";
        document.body.appendChild(script);
    });
    //readystatechange 事件,确定外部css是否加载完毕
    EventUtil.addHandler(window, "load", function () {
        var link = document.createElement("link");
        link.type = "text/css";
        link.rel = "stylesheet";

        EventUtil.addHandler(link,"readystatechange", function (event) {
            var event = EventUtil.getEvent(event);
            var target = EventUtil.getTarget(event);

            if (target.readyState == "loaded" || target.readyState == "complete") {
                EventUtil.removeHandler(target, "readystatechange", arguments.callee);
            }
        });
        link.href = "test.css";
        document.getElementsByTagName("head")[0].appendChild(link);
    });
    //以上两个函数,最重要的是一并检测readyState的两个状态,并在调用了一次事件处理程序后就将其移除

五、事件委托

1、事件委托

对”事件处理程序过多“这个问题的解决方案就是事件委托,事件委托利用了事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。比如,click事件会冒泡到document对象上,所以可以为整个页面指定一个onclick事件处理程序,而不必给每个可单击的元素分别添加。

事件委托的优点:

(1)在页面中设置时间处理程序所需的时间更少。只添加一个事件处理程序所需的DOM引用更少,花费时间少

(2)整个页面占用的内存空间更少,能够提升整体性能。

适合使用时间委托技术的事件有:click/mousedown/mouseup/keydown/keyup/keypress

2、移出事件处理程序

内存中留有那些过时不用的“空事件处理程序”,也是造成Web应用程序内存与性能问题的主要原因,解决问题的一种方法就是移除这些事件处理程序。

btn.onclick = null;

在页面卸载之前,使用onunload事件,移除所有事件处理程序

六、巩固学习的新知识

String.fromCharCode( ): 可接受一个指定的Unicode值,返回对应的字符串

/\d/.test(String.fromCharCode(EventUtil.getCharCode(event)))//判断按键按下的是否为数字

hasArrtibute( ):如果存在指定属性,则hasAttribute方法返回true,否则返回false。

specified属性:HTML DOM属性,查明是否已规定某属性

PS.《JavaScript高级程序设计》书又刷了一遍,还是又学习了很多新的知识,我觉着写博客是一种巩固学习的好方法,看书看一遍,把书上的代码敲一遍,再在博客中梳理一遍,整个知识框架就会很清晰。最近心里也有点着急,看书速度有些慢了,又买了好几本新书,不知道内推之前还来不来的及看完了。英雄不打无准备之仗,所以,加油!

时间: 2024-08-01 18:51:04

【JavaScript】事件的相关文章

javascript事件委托机制详解

以个人前端工作面试经历来看,javascript事件委托是问的最多的一类题目之一,熟悉事件委托能够了解你对于javascript的掌握程度. 面试官可能问一下问题,现在有5个li待办事件,需要实现当点击一个li时实现弹出该li的信息 <ul class="top"> <li>橘子</li> <li>香蕉</li> <li>苹果</li> <li>梨子</li> <li>

JavaScript事件委托的技术原理

如今的JavaScript技术界里最火热的一项技术应该是‘事件委托(event delegation)’了.使用事件委托技术能让你避免对特定的每个节点添加事件监听器:相反,事件监听器是被添加到它们的父元素上.事件监听器会分析从子元素冒泡上来的事件,找到是哪个子元素的事件.基本概念非常简单,但仍有很多人不理解事件委托的工作原理.这里我将要解释事件委托是如何工作的,并提供几个纯JavaScript的基本事件委托的例子. 假定我们有一个UL元素,它有几个子元素: <ul id="parent-l

JavaScript事件机制

<script type="text/javascript" src="http://runjs.cn/gist/2zmltkfa/all"></script> [前端培养-作业01]javascript事件机制 1.javascript事件模型 2.e.target与e.currentTarget是干什么的? 3.preventDefault与stopPropagation是干什么的 4.什么是dispatchEvent? 5.说一说事件代

javascript事件委托练习

JavaScript事件代理是一种简单的技巧,通过它你可以把事件处理器添加到一个父级元素上,这样就不需要为每一个元素添加或者删除事件处理器,从而避免了内存泄露或者是遍历节点造成的性能下降. 如果整个页面都采用同样事件流方式,当红色蓝色区域触发相同事件,冒泡法:先处理蓝色区域请求,捕获法:先处理红色区域请求 如果不同层的元素使用的useCapture不同,会先从最外层元素往目标元素寻找设定为capture(捕获)模式的事件,到达目标元素执行目标元素的事件后,再寻原路往外寻找设定为bubbling(

JavaScript事件---事件对象

原文:JavaScript事件---事件对象 发文不易,若转载传播,请亲注明出处,谢谢!   内容提纲: 1.事件对象 2.鼠标事件 3.键盘事件 4.W3C与IE JavaScript事件的一个重要方面是它们拥有一些相对一致的特点,可以给你的开发提供更多的强大功能.最方便和强大的就是事件对象,他们可以帮你处理鼠标事件和键盘敲击方面的情况,此外还可以修改一般事件的捕获/冒泡流的函数. 一.事件对象 事件处理函数的一个标准特性是,以某些方式访问的事件对象包含有关于当前事件的上下文信息. 事件处理三

JavaScript事件代理入门

事件代理(Event Delegation),又称之为事件委托.是 JavaScript 中常用绑定事件的常用技巧. 顾名思义,"事件代理"即是把原本需要绑定的事件委托给父元素,让父元素担当事件监听的职务. 为什么要这样做呢? 众所周知,DOM操作是十分消耗性能的.所以重复的事件绑定简直是性能杀手.而事件代理的核心思想,就是通过尽量少的绑定,去监听尽量多的事件. 下面将会用 Zepto 为大家演示怎么实现事件代理. 啊?Zepto是什么? Zepto is a minimalist J

Javascript事件冒泡,没有想象中那么糟糕

Javascript事件冒泡,没有想象中那么糟糕  提到js事件,我们可能第一时间反应的就是“如何阻止事件冒泡”:但是事件冒泡真的是如我们想象的那么糟糕吗? 1. Event 对象  Event 对象代表事件的状态,比如事件在其中发生的元素.键盘按键的状态.鼠标的位置.鼠标按钮的状态. 2. 事件句柄 (Event Handlers)  指能够使 HTML 事件触发浏览器中的行为,比如点击(onclick).鼠标悬浮(onfocus)等 3. 什么是事件冒泡  一个对象(event.srcEle

Javascript事件处理程序的3种方式

既然产生了事件,我们就要去处理它,据我了解Javascript事件处理程序主要有3种方式: 1.HTML事件处理程序 即我们直接在HTML代码中添加事件处理程序,如下面这段代码: <input id="btn1" value="按钮" type="button" onclick="showmsg();"> <script>    function showmsg(){        alert(&quo

javaScript事件(五)事件类型之鼠标事件

一.事件 二.事件流 以上内容见:javaScript事件(一)事件流 三.事件处理程序 四.IE事件处理程序 以上内容见javaScript事件(二)事件处理程序 五.事件对象 以上内容见javaScript事件(三)事件对象 六.事件对象的公共成员 以上内容见javaScript事件(四)event的公共成员 七.鼠标事件 DOM3级事件中定义了9个鼠标事件. mousedown:鼠标按钮被按下(左键或者右键)时触发.不能通过键盘触发. mouseup:鼠标按钮被释放弹起时触发.不能通过键盘

javaScript事件(三)事件对象

一.事件 二.事件流 以上内容见:javaScript事件(一)事件流 三.事件处理程序 四.IE事件处理程序 以上内容见javaScript事件(二)事件处理程序 五.事件对象 1.认识事件对象 事件在浏览器中是以对象的形式存在的,即event.触发一个事件,就会产生一个事件对象event,该对象包含着所有与事件有关的信息.包括导致事件的元素.事件的类型以及其他与特定事件相关的信息. 例如:鼠标操作产生的event中会包含鼠标位置的信息:键盘操作产生的event中会包含与按下的键有关的信息.