js的事件

来源:互联网 发布:淘宝上一千多的三星s6 编辑:程序博客网 时间:2024/06/05 18:48

事件入门

什么是事件

事件是由用户和浏览器进行交互的操作

三种事件模型内联模型

内联事件模型

作为html标签的一个属性存在的,但是这种模型已经不适合在大的项目中使用。onclick

脚本模型

但是注意的是:如果这段脚本是对整个DOM进行操作的话,必须是在DOM加载完才执行这个脚本,让事件处理函数(onclick)执行一个函数的时候,通过赋值的方式,直接将函数名赋值给事件处理函数即可,而不是为这个事件处理函数赋值为函数() 如果有括号的话会自己调用,而不是等待事件来触发

DOM2级模型

事件处理函数

onclick等事件
onkeydown 事件 按下键盘上的任意的按钮都可以输出111

    onkeydown=function(){        console.log(111);    }

onkeypress 事件 按下键盘上的字母键或者是数字键才可以触发这个事件,按下shift ctrl键都没有用

 onkeypress=function(){        console.log(111);    }

onkeyup 事件在按下键盘并释放键盘的时候才会触发这个事件

   onkeyup=function(){        console.log(111);    }

onunload 事件 在页面真个卸载的时候,才触发 比如说刷新的时候
onselect 事件 选择文本输入框的内容 释放的时候会触发这个事件

cc.onselect=function(){        console.log(11);    }

onchange 事件 文本框内改变内容并且失去焦点的时候触发
form上边的事件 这些表单必须在一个form里边
submit没有form是提交不了的,而且不是在input上边触发的,而是在form上边触发的
onresize事件 window 的事件 改变窗口的大小会触发的事件
onscroll事件 window 的事件 滚动窗体的时候会触发的事件

事件对象

事件处理的三个部分

1、DOM 2、事件处理函数 3、事件处理方法

事件对象

当触发一个事件的时候就会产生一个事件对象 浏览器通过函数把这个对象作为参数传递过来,event,所以这个对象会存在非常多的兼容性(就连得到这个对象的方式)

window.onload=function(){    var box=document.getElementById("box");    box.onclick=function(){        console.log(arguments.length)    //点击的时候会传递一个事件对象  所以这里会输出1     }}

所以下面的代码也可以

 var box=document.getElementById("box");    box.onclick=function(e){        console.log(e)    //得到的就是事件对象    }

值得注意的是,IE中都不支持这种方式来得到事件对象,上面的方式是W3C获取事件对象的方式,在IE下可以通过window的属性直接来获取
下面的代码实现了获取事件对象的兼容

box.onclick=function(e){        var event=window.event||e;        alert(event)    //得到的就是事件对象    }

鼠标事件对象跨浏览器来获得用户按下是左键?中键?右键?

window.onload=function() {    var box = document.getElementById("box");    document.onmouseup=function(e){        var event=e||window.event;        alert(getButton(e));    }}function getButton(event){    if(event){      return event.button;    }    else if(window.event){        switch(window.event.button){            case 1: return 0;            case 4: return 1;            case 2: return 2;        }    }}

跨浏览器获得鼠标点击位置在视窗的位置(不管你是放大了浏览器还是有了滚动条,都是看的是鼠标的点击的位置离视窗的位置),而且这个程序还可以输出有滚动条的时候,滚动条的离顶部的位置

 document.onmouseup=function(e){        var event=window.event||e;        alert(document.documentElement.scrollTop||document.body.scrollTop+"px"+event.clientX+"px"+ event.clientY+"px");    }

值得注意的是:获得滚动条离最顶部的距离的时候的兼容的情况
下面这个程序是获得了鼠标点击的位置离屏幕的距离

 document.onmouseup=function(e){        var event=window.event||e;        alert(event.screenX+"px"+"   "+event.screenY+"px");    }

注意:只能为alert传递一个参数
下面的函数判断是否按下修改键(shift、ctrl、alt)

window.onload=function() {    document.onclick=function(e){        alert(getKey(e));    }}function getKey(evt) {    var e = evt || window.event;    var keys = [];    if (e.shiftKey) keys.push('shift'); //给数组添加元素    if (e.ctrlKey) keys.push('ctrl');    if (e.altKey) keys.push('alt');    return keys;}

注意:上面的功能实现的是在按住shift键、ctrl键、alt键的情况下,点击屏幕会输出按下的修改键

键盘事件

keydown 按下键盘
keyup 键盘起来的时候
keypress 按下字母键盘的时候
按下键盘并返回键码keycode (键码可以返回任意键的编码,而且字母不区分大小写)

document.onkeydown=function(e){        var event=e||window.event;        alert(event.keyCode)    }

但是使用了onkeypress来返回键码,在火狐浏览器中不支持(按下键盘的时候返回的是0),在谷歌浏览器和IE中虽然支持但是区分大小写

document.onkeypress=function(e){        var event=e||window.event;        alert(event.keyCode)    }

火狐和谷歌浏览器都支持的事件对象都支持charCode,和keyPress搭配来得到字符编码,注意IE的事件对象没有这个属性

 document.onkeypress=function(e){        var event=e||window.event;        alert(event.charCode)    }

跨浏览器获得按下键盘的编码

window.onload=function() {    document.onkeypress=function(e){        alert(getCharCode(e))    }}function getCharCode(e){    var event=e||window.event;    if(typeof event.charCode=="number"){        return event.charCode;    }    else{        return event.keyCode;    }}

w3c和IE的事件

得到事件的目标

,(鼠标点在哪里,就可以得到哪里的dom对象)
跨浏览器获得事件的目标

window.onload=function() {    document.onclick=function(e){        alert(getTarget(e).tagName);    }}function getTarget(e){    var event=e||window.event;    if(event.target){        return event.target;    }    else{        return event.srcElement    }}

事件流

事件流有两种模式:冒泡和捕获
这里写图片描述
html代码

<div style="background: red;width: 100px;height: 100px" id="box">    <button > 点击</button></div>

js代码

window.onload=function() {    document.onclick=function(){        alert("documnet");    }    document.documentElement.onclick=function(){        alert("html");    }    document.body.onclick=function(){        alert("body");    }    document.getElementById("box").onclick=function(){        alert("box");    }    document.getElementsByTagName("button")[0].onclick=function(){        alert("input");    }}

在任何的浏览器点击按钮的时候依次会输出 input box body html document
取消冒泡模式

 document.getElementsByTagName("button")[0].onclick=function(e){        alert("input");        e.stopPropagation();  //IE不支持    }

只是取消了点击按钮的冒泡
跨浏览器阻止事件冒泡

function stopBubble(e){    var event=e||window.event;    (typeof event.stopPropagation=="function")? event.stopPropagation(): event.cancelBubble=true;}

事件绑定

传统事件绑定

如果一个页面有两个或者多个js脚本文件,导致会有多个window.onload这两个事件,这就会导致第一个window.onload会被覆盖,解决的方法:在使用window.onload的时候,首先要检测是否存在window.onload是否是一个函数
下面就是解决覆盖的问题

window.onload=function () {     alert("dd");}if(typeof window.onload=="function"){    var saved=null;    saved=window.onload;}window.onload=function () {    if(saved)saved();    alert("cc");}

事件切换器

<style>    .red{        background: red;        width:200px;        height: 200px;    }    .blue{        background: blue;        width:200px;        height: 200px;    }</style><body>  <div id="test" class="blue"></div></body>

js代码

window.onload=function () {    var test=document.getElementById("test");    console.log(test)    test.onclick=toBlue;}function toRed(){    this.className='red';    this.onclick=toBlue;}function toBlue(){    this.className='blue';    this.onclick=toRed;}

注意,通过匿名函数执行一个函数,那么这个函数里面的this就会代表window,但是匿名函数这个this中还是属于当前对象的

  test.onclick=function(){        alert(this);   //div        toBlue();    };    function toBlue(){    alert(this);   //会弹出window    this.className='blue';    this.onclick=toRed;}

所以下面的这个代码也实现了事件的切换

 test.onclick=function(){        toBlue.call(this);    };    function toRed(){    this.className='red';    this.onclick=toBlue;}function toBlue(){    this.className='blue';    this.onclick=toRed;}

所以传统事件的绑定有许多的缺点,所以我们要自定义函数来实现事件的绑定
有一点值得注意window.onload相当于window[“onload”]

//obj  相当于window//type   相当于onload//fn    相当于functionfunction addEvent(obj,type,fn){    removeEvent(obj,type);   //一道切的移除事件的函数    var saved=null;    if(typeof obj['on'+type]=='function'){        saved=obj['on'+type];    }    obj['on'+type]=function(){        if(saved){            saved();        }        //用它来做事件切换器   注意this        fn.call(this);    }}function removeEvent(obj,type){    if(typeof obj['on'+type]=='function') {        obj['on'+type]=null;    }}

使用新的绑定事件的方式实现事件切换器

addEvent(window,'load',function () {    var test=document.getElementById("test");    addEvent(test,'click',toBlue)})function toRed(){    this.className='red';    addEvent(this,'click',toBlue);}function toBlue(){    this.className='blue';    addEvent(this,'click',toRed);}

W3C事件绑定机制

DOM2级定义了两个事件的处理方法 添加事件 删除事件
也就是addEventListener()和removeEventListener()但是这两个方法只能在支持W3C的事件模型的浏览器上运行
传递的参数 对象.addEventListener('事件',事件处理函数,捕获(true)还是冒泡false)

window.addEventListener('load',function () {    alert(11);},false)window.addEventListener('load',function () {    alert(22);},false)

1、DM2级事件模型的绑定事件解决了覆盖的问题(一次会弹出11 22)

window.addEventListener('load',init,false)window.addEventListener('load',init,false)window.addEventListener('load',init,false)function init() {    alert(1);}

2、相同的函数多次绑定到同一个函数的时候,会自动的屏蔽(会之弹出一次1,自动屏蔽)

window.addEventListener('load',function () {    var test=document.getElementById("test");    test.addEventListener('click',toBlue,false);},false)function toRed() {    this.className="red";    this.removeEventListener('click',toRed,false);   //必须要有这一步,否则没有办法进行事件的切换    this.addEventListener('click',toBlue,false);}function toBlue() {    this.className="blue";    this.removeEventListener('click',toBlue,false); //必须要有这一步,否则没有办法进行事件的切换    this.addEventListener('click',toRed,false);}

3、可以传递this,实现事件的切换器,直接在toRed使用this

    test.addEventListener('click',function () {        alert(11);    },false);    test.addEventListener('click',toBlue,false);

4、添加一个额外的方法,会不会被覆盖或者只执行了一次,实现了点击的时候既可以弹出11也可以变色
综上所述,W3C的addEventListener和removeEventListener完美的解决了事件的绑定,但是IE8及其以下的版本都不支持DOM2级的这个事件模型,而是采用了自己的事件。
冒泡和捕获(设置true和false)

   test.addEventListener('click',function () {        alert("div");    },true);    document.addEventListener('click',function () {        alert("document")    },true);

设置为了捕获,点击div的时候,先弹出document再弹出div

IE事件处理函数

注意以下的测试必须在IE8及以下完成:
attachEvent(‘on+事件名称’,’事件处理函数’)
detachEvent(‘事件名称’,’事件处理函数’)
因为IE8以下中的事件
1、不支持捕获,
2、IE事件不能屏蔽重复的函数
3、IE中的this指向的是widow而不是DOM对象(不可以传递this)
4、传统的IE事件模型上,IE是无法接收到event对象,但是使用了attachEvent()却可以
但是也解决了
1、覆盖问题

window.attachEvent('onload',function () {    alert(1);})window.attachEvent('onload',function () {    alert(2);})

但是会先弹出2 在弹出1
让IE和W3C兼容这个事件切换器
1、跨浏览器添加事件

function addEvent(obj,type,fn) {    if(obj.addEventListener){        obj.addEventListener(type,fn,false);    }else if(obj.attachEvent){        obj.attachEvent('on'+type,fn)    }}

2、夸浏览器移除事件

function removeEvent(obj,type,fn) {    if(obj.removeEventListener){        obj.removeEventListener(type,fn);    }else if(obj.detachEvent){        obj.detachEvent('on'+type,fn)    }}

3、跨浏览器获取目标对象

function getTarget(e) {    if(e.target){        return e.target;    }    else if(window.event.srcElement){        return window.event.srcElement    }}

事件对象的其他补充

W3C的relatedTarget这个属性可以在mouseover和mouseout事件中获取从哪里移入和从哪里移出

  <span id="pox">      <div id="box"></div>  </span>

js代码

addEvent(window,'load',function () {      var box=document.getElementById("box");    addEvent(box,'mouseover',function (evt) {         alert(evt.relatedTarget)  //得到移入box的最近的对象   会弹出span    })})

跨浏览器阻止事件的默认行为

//跨浏览器阻止事件的默认行为function predefault(evt) {    var event=evt||window.event;    if(event.preventDefault)    {        event.preventDefault();    }    else{        event.returnValue=false;    }}
1 0