JavaScript 事件

JavaScript 事件

目标

  • 理解什么是事件

  • 事件流

  • 事件类型

事件的概念

事件指可以被 JavaScript 侦测到的行为。即鼠标点击、页面或图像载入、鼠标悬浮于页面的某个热点之上、在表单中选取输入框、确认表单、键盘按键等操作。事件通常与函数配合使用,当事件发生时函数才会执行。 事件名称:click/mouseover/blur("不带on")

响应某个事件的函数就是事件处理程序(事件侦听器)。 事件处理程序函数名称:onclick/onmouseove/onblur

比如说,当用户单击按钮时,就发生一个鼠标单击(onclick)事件,需要浏览器做出处理,返回给用户一个结果。 事件类型:

JavaScript

事件驱动:在js中,很多地方都是通过事件触发来驱动函数执行,从而实现某些功能。 脚本语言:在网络前端开发环境下,能够嵌入在浏览器端中的一段小程序叫做脚本语言。

事件流

事件发生时,会在发生事件的元素节点与DOM数根节点之间按照特定的顺序进行传播,这个过程称为事件流 事件流指从页面中接收事件的顺序,也可理解为事件在页面中传播的顺序。

事件发生时会在元素节点与根节点之间按照特定的顺序传播,路径所经过的所有节点都会收到该事件,这个传播过程即DOM事件流。

1、两种事件流模型

事件传播的顺序对应浏览器的两种事件流模型:捕获型事件流和冒泡型事件流。 冒泡型事件流:事件的传播是从最特定的事件目标到最不特定的事件目标。即从DOM树的叶子到根【推荐】 捕获型事件流:事件的传播是从最不特定的事件目标到最特定的事件目标。即从DOM树的根到叶子。

IE的事件流是事件冒泡,而Netscape的事件流是事件捕获,为了解决页面中事件流(事件发生顺序)的问题 事件冒泡的概念下在p元素上发生click事件的顺序应该是p -> div -> body -> html -> document

事件捕获的概念下在p元素上发生click事件的顺序应该是document -> html -> body -> div -> p [

后来 w3c 采用折中的方式,平息了战火,制定了统一的标准——先捕获再冒泡。


一般地,将事件流分为三个阶段:捕获阶段,目标阶段和冒泡阶段。

事件绑定

  • 方法一 HTML事件处理程序 <button onclick="fn()"></button>

  • 方法二:DOM0级事件处理程序 ele.onxxx = function(){} 兼容性很好,但是不允许同一个对象,多次绑定同一个事件 基本上等同于写在行间上

    <script>
     var btn = document.getElementById('btn');
     btn.onclick = function(){
     alert(1)
     }
    </script>```
    
    
  • 方法三:DOM2级事件处理程序 obj.addEventListener(type,fn,false); IE9一下不兼容,允许同一个对象,多次绑定同一个事件 第一个参数是事件名(如click); 第二个参数是事件处理程序函数; 第三个参数如果是true则表示在捕获阶段调用,为false表示在冒泡阶段调用

 <script>
 var btn = document.getElementById('btn');
 btn.addEventListener('click',function(){
 alert(1);
 })
+ 方法四  
 obj.attachEvent('on'+type,fn){}
 IE独有,允许同一个对象,多次绑定同一个事件
​
 btn.attachEvent('onclick',function(){
 alert(1);
 })
 </script>```

事件处理程序分为三类:DOM0级事件处理程序、DOM2级事件处理程序、IE事件处理程序

*   DOM0事件处理程序  //添加 btn.onclick = function(){}  //移除 btn.onclick = null;

*   DOM2事件处理程序  var handler = function(){}  //添加 btn.addEventListener('click', handler,true/false);  //移除 btn.removeEventListener('click', handler);

*   IE 事件处理的程序  var handler = function(){}  //添加 btn.attachEvent("onclick", handler);  //移除 btn.removeEvent("onclick", handler);

```window.onload = function(){
​
 var oBtn = document.getElementById('btn');
​
 oBtn.addEventListener('click',function(){
 console.log('btn处于事件捕获阶段');
 }, true);
 oBtn.addEventListener('click',function(){
 console.log('btn处于事件冒泡阶段');
 }, false);
​
 document.addEventListener('click',function(){
 console.log('document处于事件捕获阶段');
 }, true);
 document.addEventListener('click',function(){
 console.log('document处于事件冒泡阶段');
 }, false);
​
 document.documentElement.addEventListener('click',function(){
 console.log('html处于事件捕获阶段');
 }, true);
 document.documentElement.addEventListener('click',function(){
 console.log('html处于事件冒泡阶段');
 }, false);
​
 document.body.addEventListener('click',function(){
 console.log('body处于事件捕获阶段');
 }, true);
 document.body.addEventListener('click',function(){
 console.log('body处于事件冒泡阶段');
 }, false);
​
 };```

#### 事件冒泡

冒泡:同一个事件,同一个冒泡到父元素

```<body>
 <div id="content">content
 <div id="btn">button</div>
 </div>
​
 <script type="text/javascript">
 var content = document.getElementById("content");
 var btn = document.getElementById('btn');
 btn.onclick = function(){
 alert("btn");
 };
 content.onclick = function(){
 alert("content");
 };
 document.onclick = function(){
 alert("document");
 }
 </script>
</body>
</html>```

注意:一个对象的一个事件类型只能存在一个事件模型(要么冒泡要么捕获)

#### 如何获取一个事件对象

DOM中,给事件处理函数一个参数e,e就是事件对象(非IE浏览器)  该参数不需要我们传递,来源于系统传递,它上面有很多的属性,每一个属性都记载着该事件发生时的关键性数据。

在IE浏览器下可以 var event = window.event;

兼容写法 var event = e||window.event;

事件对象上右一个专门的信息是记录事件源的。

事件源对象:  event.target 火狐只有这个  event.srcElement IE只有这个

兼容写法: var target = event.target||event.srcElement;

#### 阻止事件冒泡

<!-- 案例;点击文字 弹出框 点击body弹框消失 -->

```var div = document.getElementById("div");
 var a = document.getElementById("a");
 a.onclick = function(e){
 div.style.display = "block";
 }
 document.body.onclick = function(){
 div.style.display = "none";
 }```

方法:  event.stopPropagation();  event.cancelBubble();  兼容写法

``` function stopPropagation(e){
 if(e && e.stopPropagation){
 e.stopPropagation();
 }else{
 window.event.cancelBubble = true;
 }
 }```

#### 阻止默认事件

```默认事件--a标签跳转  右键菜单
​
 <a href = 'Javascript:void(0)'></a>
 return false;        取消默认行为的执行
 e.preventDefault();  DOM提供的标准方法
 e.returnValue = false;
```javascript
var link = document.getElementById("link");
link.onclick = function(e){
 alert("hello");
}

// 右键单击的事件叫菜单事件
 document.oncontextmenu = function(ev){
​
 ev.preventDefault();  //阻止默认行为
​
 var div = document.createElement("div");
 div.style.width = "100px";
 div.style.height = "100px";
 div.style.background = "green";
 div.style.position = "absolute";
 div.style.left = event.clientX+"px"
 div.style.top = event.clientY+"px";
 document.body.appendChild(div);
 }
 document.onclick = function(){
 document.body.lastChild.remove(); //lastChild 最后一个节点
 }
​

兼容写法:

function stopDefault(e){
 if(e && e.preventDefault){
 e.preventDefault();
 }else{
 window.event.returnValue = false;
 }
}

事件委托

 ul.onclick = function(e){
 var event  = e||window.event;
 var target = event.srcElement||event.target;
 console.log(target);
 }```

## Event对象的概念

```JavaScript与HTML的交互是通过用户或浏览器操作页面时发生的事件(Event)来处理的。
当页面加载时,它被称为事件(Event)。当用户单击按钮时,单击也是一个事件(Event)。其他示例包括按任意键、关闭窗口、调整窗口大小等事件(Event)。
我们可以使用这些事件(Event)来执行JavaScript的响应,比如响应按钮、向用户显示消息、验证数据,等等。
事件(Event)是文档对象模型(DOM)级别3(原文:Document Object Model (DOM) Level 3)的一部分,每个HTML元素都包含一组可以触发JavaScript代码的事件(Event)。

Event对象

Event对象相关属性

button  返回当事件被触发时,哪个鼠标按钮被点击。
clientX 返回当事件被触发时,鼠标指针的水平坐标。
clientY 返回当事件被触发时,鼠标指针的垂直坐标。
ctrlKey 返回当事件被触发时,”CTRL” 键是否被按下。
metaKey 返回当事件被触发时,”meta” 键是否被按下。
relatedTarget   返回与事件的目标节点相关的节点。
screenX 返回当某个事件被触发时,鼠标指针的水平坐标。
screenY 返回当某个事件被触发时,鼠标指针的垂直坐标。
shiftKey    返回当事件被触发时,”SHIFT” 键是否被按下。

cancelBubble    如果事件句柄想阻止事件传播到包容对象,必须把该属性设为 true。
fromElement 对于 mouseover 和 mouseout 事件,fromElement 引用移出鼠标的元素。
keyCode 对于 keypress 事件,该属性声明了被敲击的键生成的 Unicode 字符码。对于 keydown 和 keyup
offsetX,offsetY 发生事件的地点在事件源元素的坐标系统中的 x 坐标和 y 坐标。
returnValue 如果设置了该属性,它的值比事件句柄的返回值优先级高。把这个属性设置为
srcElement  对于生成事件的 Window 对象、Document 对象或 Element 对象的引用。
toElement   对于 mouseover 和 mouseout 事件,该属性引用移入鼠标的元素。
x,y 事件发生的位置的 x 坐标和 y 坐标,它们相对于用CSS动态定位的最内层包容元素。

Event对象相关方法

srcElement/target:事件源,就是发生事件的元素;
relatedTarget:返回与事件的目标节点相关的节点;
fromElement,toElement:对于 mouseover 和 mouseout 事件,fromElement 引用移出鼠标的元素,toElement引用移入鼠标的元素;
currentTarget:返回其事件监听器触发该事件的元素;
timeStamp:返回事件生成的日期和时间;
eventPhase:返回事件传播的当前阶段,1表示捕获阶段,2表示处于目标,3表示冒泡阶段;
detail:表示的是与事件相关的细节信息
bubbles:返回布尔值,指示事件是否是起泡事件类型;
cancelable:返回布尔值,表示是否可以取消事件的默认行为;
cancelBubble:一个布尔属性,默认是false。把它设置为true的时候,将阻止事件进一步起泡到包容层次的元素;(e.cancelBubble = true; 相当于 e.stopPropagation();)
returnValue:一个布尔属性,设置为false的时候可以阻止浏览器执行默认的事件动作;(e.returnValue = false; 相当于 e.preventDefault();)
defaultPrevented:表示是否调用了preventDefault()
initEvent(eventType,canBubble,cancelable):初始化新创建的 Event 对象的属性;
preventDefault(): 通知浏览器不要执行与事件关联的默认动作;
stopPropagation():不再派发事件

DOM0级事件处理程序

分为2个:一是在标签内写onclick事件

二是在JS写onlick=function(){}函数

DOM2级事件处理程序

只有一个:监听方法,有两个方法用来添加和移除事件处理程序:addEventListener()和removeEventListener()。

它们都有三个参数:第一个参数是事件名(如click);

第二个参数是事件处理程序函数;

第三个参数如果是true则表示在捕获阶段调用,为false表示在冒泡阶段调用。

addEventListener():可以为元素添加多个事件处理程序,触发时会按照添加顺序依次调用。 removeEventListener():不能移除匿名添加的函数。

IE事件处理程序

IE中采用的事件流是事件冒泡,先从具体的接收元素,然后逐步向上传播到不具体的元素。

事件类型

UI事件

追踪用户在页面中的各种行为,如监听表单的输入 focus(获得焦点) blur(失去焦点),与表单的各种交互,submit change select

焦点事件

onfocus 事件在对象获得焦点时发生。 onblur 事件会在对象失去焦点时发生。

鼠标事件

跟踪鼠标当前定位(mouseover mouseout),跟踪鼠标单击(mouseup mousedown click)

click

用户单击鼠标主按钮(一般为左边按钮)或者在获得焦点的前提下按回车键时触发。 click()方法也可以触发click 事件。

dblclick

dblclick用户双击鼠标主按钮(一般为左边按钮)时触发。 mousedown:按下任意鼠标按钮时触发。 mouseup:释放鼠标按钮时触发。

mouseenter

鼠标光标从元素外部首次移动到元素范围之内时触发,这个事件不冒泡,而且在光标移动到后代元素上不会重复触发。通常和mouseleave搭配使用。 mousemove:鼠标光标在元素内部移动时重复地触发。 mouseover:鼠标光标位于一个元素外部,首次移动到另一个元素边界之内(包括后代元素)时触发。

键盘事件

keyup keydown keypress

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,458评论 6 513
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,030评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,879评论 0 358
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,278评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,296评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,019评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,633评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,541评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,068评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,181评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,318评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,991评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,670评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,183评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,302评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,655评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,327评论 2 358