温故而知新-JavaScript事件与兼容性相关

w简书的markdown不支持[toc]? 😭

不知不觉,从开始做android的项目后就很少写JS了,最近项目中需要用到大量的H5,也来凑凑HTML5开发的热闹。。。当然前提要学好JS,好记性不如烂笔头,开始学着写点笔记,提升学习效率~

这里只是记录一些比较容易忘记,API之类的需要时再去查阅

[toc]

事件对象

接受对象的差异性

W3C可直接通过参数接收事件对象,而IDE自己定义了一个Event对象,通过window.event获取。

兼容获取事件对象的代码
    <input type="button" id="btn" value="提交"/>
    <script>
        var btn = document.getElementById("btn");
        btn.onclick = function(event){
            var e = event || widnow.event;
            alert(e);
        }
    </script>

鼠标事件

鼠标事件的兼容性问题

onmousemove:鼠标移动
onmousedown:鼠标点击
onmouseup:鼠标松开
onmouseover:鼠标移动到元素区域内
onmouseout :鼠标移出元素

在这三个事件对象中,有一个button属性,表示按下或者释放的按钮,遗忘的是对于这个button属性,坑爹的IE也与W3C不同(怪不得你爹不要你了)

W3C中的button属性

IE中的button属性

可以看出,IE和W3C在button属性上各个数值所表示的按钮和状态都不一样,但是一般我们只需要兼容W3C那三种就好了
兼容代码

 function getButton(evt) {
            var e = evt || window.event;
            if (evt) {
                return e.button;
            } else
                if (window.event) {
                    switch(e.button) {
                        case 1 :
                            return 0;
                        case 4 :
                            return 1;
                        case 2 :
                            return 2;
                }
            }
        }

        document.onmouseup = function (evt) {
            if (getButton(evt) == 0) {
                alert('按下了左键!');
            } else if (getButton(evt) == 1) {
                alert('按下了中键!');
            } else if (getButton(evt) == 2) {
                alert('按下了右键!' ); }
        };

鼠标事件-可视区和坐标的获取

可通过clienX,screex获取,这个就不记录了,查一下文档即可

键盘事件

onkeydown
onkeypress:只对能在屏幕上输出字符的按钮有效果
onkeyup


属性:
keyCode:键码---获取一个代码,与键盘特定的键对应,与ASCII码中对应的编码相同(不区分大小写)
charCode:字符编码 --- 只有在keypress中才包含值,对应的是键所代码的字符的ASCII编码(区分大小写)
document.onkeypress = function (event) {
    alert("charCode == "+ event.charCode); //得到相应的 charCode

};
document.onkeydown = function (event) {
    alert("keyCode == "+ event.keyCode); //得到相应的 keyCode

};

兼容性问题:

不同浏览器中,获取的keyCode(键码)和charCode(字符编码)有可能不一样,要谨慎操作

事件对象的其他属性

![](http://upload-images.jianshu.io/upload_images/205088-36015df534702463.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

事件冒泡

事件流:当几个具有事件的元素叠在一起的时候,那么你点击一个元素后,所有层叠在你点击范围内的元素都会触发事件。

来个简单的图感受一下。

屏幕快照 2016-04-17 上午12.01.00.png

Button,紫色和蓝色的DIV都具有点击事件,因为Button在最内层,当点击button时,click事件会从内往外触发----这就是事件冒泡(特征:从里往外触发)
事件捕获:与事件冒泡相反,是从外往内触发

阻止冒泡

从前面的==事件的其他属性==中看到,关于阻止事件冒泡IE和W3C有不同的属性

IE:是通过cancelBubble = true 取消事件冒泡
W3C:调用stopProgagation()方法取消事件冒泡

阻止的兼容方法

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

事件的绑定

事件的绑定有两种方式
一,传统的事件绑定,分为内联模型,脚本模型
二,DOM2级的现代事件绑定

传统的事件绑定

内联模型

基本上很少用,维护起来简直想杀人。。。
下面这两种形式

    <input value="点击" id="btn" type="button" onclick="alert('aaa')">
   <input value="点击" id="btn" type="button" onclick="btnOnclick()">

脚本模型

即用JavaScript获取DOM设置事件

传统事件绑定的问题

一、多次绑定会被覆盖

很直观的问题,重复绑定会覆盖掉前面的
  /*缺点1:绑定多次会被覆盖 */
  window.onload = function(){
    alert("onload 111111");
  }
  window.onload = function(){
    alert("onload 2222222");
  }

二、this的指向问题

  var myDiv = document.getElementById("myDiv");
  myDiv.onclick = toBlue;
  function toBlue(){
      alert(this);//第一次就是DivElement   第二次就是window了
      this.className = "blue";
      this.onclick = toRed;
  }
  function toRed(){
      this.className = "red";
      this.onclick = function(){
            toBlue();
      }
  }

三、too much recursion的问题

当你不停的add事件时,可能会报出too much recursion的错误,这是因为你积累了太多的保存事件,太多递归导致浏览器卡死。
解决方法:用完的事件,立即处理掉

        var myDiv = document.getElementById("myDiv");
        //可以通过[]的形式获取绑定事件
        myDiv['onclick'] = function(){
            alert("aaa");
        };

        /**
         *  obj : 要移出的元素
         *  type: 要移出的事件类型 click等
         **/
        function removeEvent(obj,type){
            if(obj['on'+type]) obj['on'+type] = null;
        }

W3C事件处理

DOM2级中,定义了addEventListener和removeEventListener方法。最后一个参数 true:表示捕获,false:表示冒泡

一,解决了this的指向问题,再也不怕too much recursion了

我们将上面this指向的代码稍微修改一下
            var myDiv = document.getElementById("myDiv");

            myDiv.addEventListener('click',toBlue);
            function toBlue(){
                alert(this);//都是DivElement
                this.className = "blue";
                this.addEventListener('click',toRed);
            }
            function toRed(){
                this.className = "red";
                myDiv.addEventListener('click',function(){
                    toBlue();
                });
            }

二,解决重复绑定覆盖的问题

 var myDiv = document.getElementById("myDiv");
 myDiv.addEventListener('click',function(){
     alert("event 11111");
 })
 /**
 * 不再覆盖,两个都会执行,共存
 * */
 myDiv.addEventListener('click',function(){
     alert("event 222222");
 })

IE的事件处理函数

IE9就全面支持W3C的事件函数了,这里就做个简单的了解

提供了两个方法:
attachEvent()
detachEvent()

几个不同点

1,IE不支持捕获,只支持冒泡
2,IE不能屏蔽重复的函数
3,IE中this指向的是window对象
4,之前说到,IE在传统事件中接收不到event事件对象的
但是attchEvent可以做到。。。真是让人爪机

不想装个IE浏览器,这就不测试了,做个简单的记录,方便以后用到的时候查询

添加/删除事件,得到事件对象的兼容代码

    //添加事件兼容
    function addEvent(obj, type, fn) {
        if (obj.addEventListener) {
            obj.addEventListener(type, fn);
        } else
                if (obj.attachEvent) {
                   obj.attachEvent('on' + type, fn); }
    }

    //移除事件兼容
    function removeEvent(obj, type, fn) {
        if (obj.removeEventListener) {
            obj.removeEventListener(type, fn);
        } else if (obj.detachEvent) {
             obj.detachEvent('on' + type, fn);
        }
    }
    //得到事件目标
    function getTarget(evt) { if (evt.target) {
        return evt.target;
    } else if (window.event.srcElement) {
        return window.event.srcElement; }
    }

事件其他补充(主要是兼容方面)

获取移入和移出的DOM对象的兼容问题

 W3C版:事件对象属性:relatedTarget
 IE版:fromElement 和 toElement,分别对应 mouseover 和 mouseout。

不同的实现,又需要兼容的代码~

 function getTarget(evt) {
        var e = evt || window.event;
        if (e.srcElement) {//如果支持,就是IE浏览器(srcElement:事件目标)
            if (e.type == 'mouseover') {
                return e.fromElement;
            } else if (e.type == 'mouseout') {
                return e.toElement;}
        } else if (e.relatedTarget) {
            //如果支持 relatedTarget,表示 W3C ;
            return e.relatedTarget;
        }
    }

取消事件默认行为的兼容性问题

场景:取消超链接的默认行为.

解决方法一:
设置 return false。
缺点:
1)、必须写在最后,那么中间的代码执行后,
可能执行不到return false;(例如中间报错了,但是页面依旧会跳转)
2)、如果写在最前面,那么就无法做一些跳转判断了(通过一段逻辑判断后才决定是否跳转)
` <a id="aLink" href="http://baidu.com">aaaa</a>`
    var aLink = document.getElementById("aLink");
    aLink.onclick = function(){
        /**
         *
         * */
        var person = function(){

        }
        var p = new Person();
        p.show();//这里没有show方法,报错了,所以后面的return false没有执行到,页面依旧跳转了
        return false;
    }
解决方法二:取消事件的默认行为

W3C:event.preventDefault(); IE:window.event.returnValue = false;

头疼,又需要兼容。。。

兼容代码
    function preDef(event) {
        var e = event || window.event;
        if(e.preventDefault) {
            e.preventDefault();
        }else {
            e.returnValue= false;
        }
    }

oncontextmenu事件

可用于取消右键事件,提升浏览器性能

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

推荐阅读更多精彩内容