• js事件在不同浏览器之间的差异


       1. 介绍

      javascript与HTML之间的交互是通过事件实现的。事件,就是文档或浏览器窗口中发生的一些特定的交互瞬间。只不过在当年还没有统一标准的时候,各个浏览器厂商都制定了自己的标准,当我们编写代码时就要考虑不同浏览器之间的各种差异。

      事件流一般包括三个阶段:事件捕获阶段,处于目标阶段和事件冒泡阶段。所有现代浏览器都支持时间冒泡,但在具体实现上有一些差异,IE5.5及更早版本中的事件冒泡会跳过<html>元素(从<body>直接跳到document),IE9、Firefox、Chrome和Safari则将事件一直冒泡到window对象;老版本的浏览器不支持事件捕获。

       2. 不同浏览器之间的差异

      其实这个跟之间的写过的文章浏览器检测-js中,我们也有提到过一些。各个浏览器之间确实存在差异,这是我们不可避免的。我们能做的就是尽量去寻找一个通用的方法,如果没有通用的方法,那我们只能针对不同浏览器的特性分别写代码了。当然,也有很多人专门写了一些JS代码来消除这些差异,比如jQuery,在我们jQuery时很少会考虑浏览器的差异,那是因为jQuery内部已经为我们处理好了。IE什么的最讨厌了。

       2.1 添加事件的方法

      我们通常是这样为某元素添加事件的:

    var btn = document.getElementById("myBtn");
    btn.addEventListener("click", function(){
        //处理代码
    })

      这样就能为id是myBtn的元素绑定一个click事件了。其实addEventListener有三个参数,只不过我们通常会省略掉第三个参数:

      第一个参数:添加事件的类型,比如click, mouseover, mousemove等等,这里的事件类型是没有on,不是"onclick";

      第二个参数:事件处理函数,这里用来添加需要执行的代码;

      第三个参数:在哪个阶段调用事件处理程序,布尔值。若为true,表示在捕获阶段处理;若为false则在冒泡阶段进行处理。默认为false。

      而且如果我们用addEventListener为同一个元素添加多个相同事件时,事件会按添加的顺序依次执行。

      IE中为某元素添加事件的方法:

    var btn = document.getElementById("myBtn");
    btn.attachEvent("onclick", function(){
        //处理代码
    })

      这里我们能够很明显地看到两者的不同:IE中使用attachEvent添加事件,而且添加事件的类型有"on",这个方法只有两个参数,因为用attachEvent添加的事件会被添加到冒泡阶段。

      第一个参数:添加事件的类型,比如有"onclick", "onmouseover"等,这里的事件类型是带有"on"的;

      第二个参数:事件处理函数,用来处理程序。

      如果用attacheEvent为某一元素添加多个相同事件时,最后添加的事件会首先被执行。

       2.2 事件对象event

      IE和其他浏览的event对象是不同的。在其他浏览器中若要使用时,都要传入event对象,而在IE中,event却是window对象的一个属性。

    var btn = document.getElementById("myBtn");
    
    /* 非IE */
    btn.addEventListener("click", function(event){
        //处理代码
        alert(event.type);
    })
    
    /* IE */
    btn.attachEvent("onclick", function(){
        //处理代码
        var event = window.event;
        alert(event.type);
    })

      不过在实际中,我们却不能把这两个并列地写,因为其中一个方法在某一个浏览器中肯定是没有定义的,会报错。当我们确实要使用event对象时,我们可以这样写:

    function(event){
        //处理代码
        event = event || window.event;
        alert(event.type);
    }

      这样就能保证event对象必然是存在可用的。

       2.3 event中的属性/方法

      不同浏览器的event存在方法不同,而且各自的属性与方法也不尽相同。

    属性/方法 类型 读/写 说明
    bubbles Boolean 只读 表明事件是否冒泡
    cancelable Boolean 只读 是否可以取消事件的默认行为
    currentTarget Element 只读 其事件处理程序当前正在处理事件的那个元素
    eventPhase Integer 只读 调用事件处理程序的阶段:1捕获阶段,2处于目标,3冒泡阶段
    preventDefault() Function 只读 取消事件的默认行为。只在cancelable为true时才可使用该方法
    stopPropagation() Function 只读 取消事件的进一步捕获或冒泡。只在bubbles为true时才可使用该方法
    target Element 只读 真正触发事件的那个元素
    type String 只读 被触发事件的类型

      IE中event的属性与方法:

    属性/方法 类型 读/写 说明
    cancelBubble Boolean 读/写 是否取消事件的进一步冒泡。为true时取消冒泡,默认为false
    returnValue Boolean 读/写 是否取消事件的默认行为。为false时取消事件的默认行为,默认为true
    srcElement Element 只读 事件的目标
    type String 只读 被触发事件的类型

      我们从两个表格中能够看到,还是有很多的属性和方法是相似的,虽然名称和使用的方法不同,但最终的目的都是一样的。

      不过为了在各个浏览器之间的通用,我们可以这样写:

    function(event){
        //处理代码
        event = event || window.event;
        
        //取消事件的默认行为
        if (event.preventDefault) {
            event.preventDefault();
        }else{ 
            event.returnValue = false;
        }
        
        //取消事件的进一步冒泡
        if(event.stopPropagation){
            event.stopPropagation();
        }
        else{
            event.cancelBubble = true;
        }
    }

      首先判断浏览器是否支持该属性或方法,如果支持则使用该属性或方法,否则使用另一个属性或方法。

       3. 总结

      浏览器兼容是前端程序员永远的痛,不只是在js,css也有很大的不同。不过在标准越来越统一的大环境下,将来要考虑的差异性就会少多了。这里要说一句:IE11现在已经废除了attachEvent方法。

  • 相关阅读:
    经过改良后可以导出超过70000条数据的导出公共excel类
    一个简单的文档导出公共处理类
    网上找的正则验证邮箱手机等代码
    springMvc IE浏览器 前台中文参数 乱码问题解决方法
    国际化
    验证框架
    基于注解来装配Bean的属性
    aop
    自定义属性编辑器
    propertyPlaceholderConfigurer 和propertyOverrideConfigurer
  • 原文地址:https://www.cnblogs.com/xumengxuan/p/3408984.html
Copyright © 2020-2023  润新知