事件(上)

事件对象(上)

事件复习

事件三要素: 事件源  + 事件名称 +  事件处理程序

事件源 : 谁触发这个事件 (按钮  btn)

事件名称 : 触发了什么事件 (点击click事件)

事件处理程序 : 事件触发后要执行的代码(函数形式)----可以是有名字的函数,要不要加小括号?不加

事件类型

在事件对象中有个一个属性type可以获取到当前事件的类型。

window.onload=function(e){

varev=e||window.event;

console.log(ev.type);// load

}

鼠标事件

事件                                                     描述

click                                                     左键单击

contextmenu                                       右键单击

dblclick                                                双击

mousedown                                        左键按下

mouseup                                            左键弹起

mouseover                                         鼠标放上去(在子元素上也会触发)

mouseout                                           鼠标离开

mouseenter                                        鼠标放上去

mouseleave                                        鼠标离开

mousemove                                        鼠标移动事件

mousewheel                                        鼠标滚轮事件

注意:鼠标滚轮事件有兼容性问题,在IE、Chrom中是mousewheel,在FireFox中是DOMMouseScroll,且在FirFox中不能使用on来绑定。在IE和Chrom中向上滚动,事件对象中的wheelDelta是120,向下滚动是-120,在FirFox中向上滚动,事件对象中的e.detail是3,向下滚动是-3。

案例:星星评分

<body>

<imgsrc="./images/rank_3.gif"alt=""><imgsrc="./images/rank_4.gif"alt="">

<imgsrc="./images/rank_3.gif"alt=""><imgsrc="./images/rank_4.gif"alt="">

<imgsrc="./images/rank_3.gif"alt=""><imgsrc="./images/rank_4.gif"alt="">

<imgsrc="./images/rank_3.gif"alt=""><imgsrc="./images/rank_4.gif"alt="">

<imgsrc="./images/rank_3.gif"alt=""><imgsrc="./images/rank_4.gif"alt="">

</body>

<scripttype="text/javascript">

varimgs=document.querySelectorAll("img");

for(vari=0;i<imgs.length;i++){

imgs[i].index=i;

imgs[i].onmouseover=function(){

for(varj=0;j<=this.index;j++){

if(j%2==0){

imgs[j].src='./images/rank_1.gif'

}else{

imgs[j].src='./images/rank_2.gif'

           }

       }

for(varj=this.index+1;j<imgs.length;j++){

if(j%2==0){

imgs[j].src='./images/rank_3.gif'

}else{

imgs[j].src='./images/rank_4.gif'

           }

       }

   }

}

</script>

效果图:

星星评分效果

浏览器事件

事件                                          描述

load                                          加载

unload                                      关闭

scroll                                        滚动

resize                                       大小改变

键盘事件

事件                                               描述

keydown                                        按下

keyup                                             弹起

keypress                                        敲打

键盘事件除了用window可以触发之外,还可以使用document,或者表单元素。总之是可以选中的元素。例如div就不行。

表单事件

事件                                               描述

submit                                           提交表单

focus                                             获取焦点

blur                                               失去焦点

change                                         内容改变并失去焦点

input                                             input的value值改变

使用说明:input事件在低版本的IE中不兼容,使用onpropertychange代替。

事件流

每个事件发生的时候,都会有一个触发并执行的过程,也就是事件的传播过程,我们称之为事件流。

简单来说,事件流就是事件从发生到执行结束的流程。

事件流包含3个阶段:捕获阶段、目标阶段、冒泡阶段

事件捕获阶段:事件开始由顶层元素触发,然后逐级向下传播,直到目标元素,依次执行其身上绑定的事件。

事件目标阶段(处理阶段):触发当前自身的事件。

事件冒泡阶段:事件由目标元素先接收,然后逐级向上传播,达到最顶层元素,依次执行其身上绑定的事件。

事件流

事件执行的流程是先捕获阶段——》再目标元素阶段——》最后冒泡阶段。

目标元素的事件是在目标阶段执行,其他事件会在冒泡阶段执行。每个事件只会执行一次,也就是说如果在冒泡阶段执行了事件,就不会在捕获阶段执行。

例:

<body>

<style>

#big{

width:200px;

height:200px;

border:1pxsolid#000;

   }

#middle{

width:150px;

height:150px;

background:#abcdef;

   }

#small{

width:100px;

height:100px;

background:red;

   }

</style>

<divid="big">

   大盒子的内容

<divid="middle">

       中盒子的内容

<divid="small">

           小盒子的内容

</div>

</div>

</div>

</body>

<scripttype="text/javascript">

big.onclick=function(){

console.log(this.innerText);

console.log("大盒子的内容完毕");

}

middle.onclick=function(){

console.log(this.innerText);

console.log("中盒子的内容完毕");

}

small.onclick=function(){

console.log(this.innerText);

console.log("小盒子的内容完毕");

}

</script>

访问效果:

冒泡示例图

点击小盒子,发现小盒子事件完毕后,中盒子的事件也被触发了,接着大盒子的事件也被触发了。这就是说目标元素的事件在目标阶段执行,其他事件会在冒泡阶段执行。

<font color="blue">思考:如何让事件在捕获阶段执行?</font>

需要使用另外一种事件绑定方式。

事件的绑定方式

事件可以绑定在行内:

<buttononclick="alert(123)">按钮1</button>

<buttononclick="fn()">按钮2</button>

<script>

functionfn(){

alert(456)

   }

</script>

使用on加事件类型绑定事件:

使用on来绑定事件有弊端:同一个事件只能给一个元素绑定一次。

<body>

<buttonid="btn">按钮</button>

</body>

<script>

btn.onclick=function(){

console.log("第一次单击");

}

btn.onclick=function(){

console.log("第二次单击");

}

</script>

访问效果:

事件覆盖

解决方案:

使用addEventListener()

语法:

obj.addEventListener(type,handle,false);

# 参数1:给元素绑定的事件类型,如:click,mouseover。。。

# 参数2:处理事件的函数

# 参数3:是否在冒泡阶段执行,true在捕获阶段执行,false在冒泡阶段执行

例:

<body>

<buttonid="btn">按钮</button>

</body>

<script>

document.getElementById("btn").addEventListener("click",handle,false);

functionhandle(){

console.log("第一次点击");

}

document.getElementById("btn").addEventListener("click",handle1,false);

functionhandle1(){

console.log("第二次点击");

}

</script>

效果:

同一类型事件给元素绑定多次

使用说明:这个方法在IE低版本浏览器中不兼容。在IE低版本浏览器中使用attachEvent()来代替。

语法:

obj.attachEvent('on'+type,handle);

# type表示事件类型

# handle表示处理事件的函数

使用说明:这种写法,有个特点:顺序注册事件,执行的时候是倒叙执行。

例:

<body>

<buttonid="btn">按钮</button>

</body>

<script>

document.getElementById("btn").attachEvent("onclick",handle,false);

functionhandle(){

console.log("第一次点击");

}

document.getElementById("btn").attachEvent("onclick",handle1,false);

functionhandle1(){

console.log("第二次点击");

}

</script>

运行结果:

IE中绑定事件执行

让事件在捕获阶段执行:

<body>

<style>

#big{

width:200px;

height:200px;

border:1pxsolid#000;

   }

#middle{

width:150px;

height:150px;

background:#abcdef;

   }

#small{

width:100px;

height:100px;

background:red;

   }

</style>

<divid="big">

   大盒子的内容

<divid="middle">

       中盒子的内容

<divid="small">

           小盒子的内容

</div>

</div>

</div>

</body>

<script>

document.getElementById("small").addEventListener("click",Click,true);

document.getElementById("middle").addEventListener("click",Click,true);

document.getElementById("big").addEventListener("click",Click,true);

functionClick(){

console.log(this.innerText);

}

</script>

执行效果:

捕获阶段执行事件

点击小盒子的时候,先触发大盒子的事件,再触发中盒子的事件,最后触发小盒子的事件。

在IE低版本浏览器中的事件没有捕获阶段,只有冒泡阶段。

通用的绑定和解绑事件

将三种方式的绑定和解绑综合起来的兼容写法:

绑定函数

functionbind(ele,type,callback){

    if(ele.addEventListener){

        ele.addEventListener(type,callback,false);

    }elseif(ele.detachEvent){

        ele.attachEvent("on"+type,callback);

}else{

ele["on"+type]=callback;

   }

}

参数说明:

1. ele:将要绑定事件的对象

2. type:事件类型

3. callback:处理事件的函数

解绑函数

functionunbind(ele,type,callback){

    if(ele.addEventListener){

        ele.removeEventListener(type,callback,false);

    }elseif(ele.detachEvent){

ele.detachEvent("on"+type,callback);

}else{

ele["on"+type]=null;

   }

}

在实际开发中,给父元素和子元素绑定事件的场景是很常见的。例:

<font color="blue">思考:如何让事件不冒泡?</font>

需要使用事件对象。

事件对象

浏览器为事件提供了一个对象,用来记录事件的各种具体信息,例如,鼠标点击的位置、鼠标按键的信息、键盘的键码。。。

这就是事件对象。

<body>

<buttonid="btn">按钮</button>

</body>

<scripttype="text/javascript">

btn.onclick=function(){

console.log(window.event);

}

</script>

点击访问结果:

事件对象

从结果中可以看出,这个事件对象中包含了事件的类型、鼠标点击的位置,在屏幕中和在浏览器中的位置。点开的话,里面还有很多信息。

还有另外一种写法:

btn.onclick=function(e){

console.log(e);

}

以前的时候,前面的写法是针对IE浏览器的,下面的写法是针对W3C标准浏览器的。上面的写法,现在基本都兼容了;下面这种写法,在IE低版本浏览器中还不兼容。

兼容所有浏览器的写法:

btn.onclick=function(e){

varev=e||window.event

console.log(ev);

}

使用的是短路运算法。

vara=1;

varb;

// 将赋值作为条件,永远是成立的

if(b=2){

console.log(b);// 2

}

console.log(b);// 2

// 在或者的逻辑中,如果第一个条件为true,则不再执行第二个条件

if(a>0||(b=3)){

console.log(b);// 2

}

console.log(b);// 2

// 只有第一个条件是false的时候才会执行第二个条件

if(a>1||(b=3)){

console.log(b);// 2

}

console.log(b);// 2

// 逻辑运算符||两边都会转为布尔值进行判断

// 短路运算

varc=0||1;

console.log(c);// 1

// 因为0转为布尔值是false,所以赋值的时候0没有执行

/* 相当于下面这几行代码 */

if(0){

    c=0;

}elseif(1){

    c=1;

}else{

c=undefined;

}

// 当e是false的时候,将window.event赋值给ev

ev=ev||window.event;

如果是行内绑定的事件,就将事件对象当做参数传进来即可。<font color="red">且必须是event。</font>

例:

<buttononclcik="fn(event)">

   按钮

</button>

<script>

functionfn(e){

console.log(e);

   }

</script>

阻止事件冒泡

在事件对象中,有一个方法用来阻止事件冒泡,这个方法叫做stopPropagation。

例:

<body>

<style>

#big{

width:200px;

height:200px;

border:1pxsolid#000;

   }

#middle{

width:150px;

height:150px;

background:#abcdef;

   }

#small{

width:100px;

height:100px;

background:red;

   }

</style>

<divid="big">

   大盒子的内容

<divid="middle">

       中盒子的内容

<divid="small">

           小盒子的内容

</div>

</div>

</div>

</body>

<scripttype="text/javascript">

big.onclick=function(){

console.log(this.innerText);

console.log("大盒子的内容完毕");

}

middle.onclick=function(){

console.log(this.innerText);

console.log("中盒子的内容完毕");

}

small.onclick=function(e){

varev=e||window.event;

ev.stopPropagation();

console.log(this.innerText);

console.log("小盒子的内容完毕");

}

</script>

此时,点击小盒子,不再触发父元素的事件。

阻止事件冒泡在IE浏览器中有兼容问题,在低版本IE浏览器中,需要使用另外一种写法:

ev.cancelBubble=true;# IE低版本浏览器

例:

small.onclick=function(e){

varev=e||window.event;

ev.cancelBubble=true;

console.log(this.innerText);

console.log("小盒子的内容完毕");

}

为了兼容IE低版本浏览器,使用兼容写法:

small.onclick=function(e){

console.log(this.innerText);

console.log("小盒子的内容完毕");

varev=e||window.event;

if(ev.stopPropagation){

    ev.stopPropagation

}else{

ev.cancelBubble=true;

   }

}

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

推荐阅读更多精彩内容