zoukankan      html  css  js  c++  java
  • Javascript的DOM中兼容问题以及解决兼容问题的方法

    一、获取非行内样式的方法和它的兼容问题及解决方式

    方 法 一:getComputedStyle(obox,false) 

    第一个参数表示要获取的对象,第二个值指定一个要匹配的伪元素的字符串。必须对普通元素省略(或null)false也可以。主要针对正常浏览器

    方 法 二:Element.currentStyle  在IE浏览器中使用

    解决兼容问题的方式:

    function getStyle(ele,attr){
        if(ele.currentStyle){
            return ele.currentStyle[attr];
        }else{
            return getComputedStyle(ele,false)[attr];
        }
    }

    案例:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
        <style>
             #box{100px;height:100px;border: solid 1px black;}
        </style>
    </head>
    <body>
            <div id="box" style="background: red"></div>
    </body>
    <script>
        var obox = document.getElementById("box")
        // 行内样式;是可以获取和设置的
        console.log(obox.style.background);// red
        // 用style操作获取不了非行内样式
        console.log(obox.style.border);// 为空
    
        // 如何获取非行内样式,只能获取不能设置;
        // Window.getComputedStyle()方法返回一个对象,该对象在应用活动样式表并解析这些值可能包含的任何基本计
        // 算后报告元素的所有CSS属性的值。 私有的CSS属性值可以通过对象提供的API或通过简单地使用CSS属性名称进行索引来访问。
        console.log(getComputedStyle(obox,null));
        //第一个参数表示要获取的对象,第二个值指定一个要匹配的伪元素的字符串。必须对普通元素省略(或null)false也可以。
        console.log(getComputedStyle(obox,null).width);//100px;
    
        // 由于getComputedStyle()存在兼容,另一个获取方法
        // Element.currentStyle可以在ie里用
        console.log(obox.currentStyle);//undefined
        // console.log(obox.currentStyle.width)
    
    
        // 为了解决兼容问题,可以将这两种放进一个封装函数中
    
        function getStyle(ele,attr){
            var a = "";
            if(ele.currentStyle){
                a = ele.currentStyle[attr];//attr是一个变量,变量用中括号
            }else {
                a = getComputedStyle(ele,false)[attr];
            }
            return a;
        }
    
    
    
        getStyle(obox,"width")
    
    
        // 简易写法
        function getStyle(ele,attr){
            
            if(ele.currentStyle){
                return ele.currentStyle[attr];//attr是一个变量,变量用中括号
            }else {
                return getComputedStyle(ele,false)[attr];
            }
        }
    
    
    
        getStyle(obox,"width")
        
        // 这样绝大部分浏览器兼容问题就解决了
        
        
    </script>
    </html>

    二、获取事件对象的方法和它的兼容问题及解决方式

    1.IE中:          window.event
     
    2.正常浏览器中:    对象.on事件 = function(event){}
     
    解决兼容问题的方式:
        document.onclick = function(eve){
           var e = eve || window.event;
       }

    案例:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
        <style>
            .box{100px;height:100px;background: red;}
        </style>
    </head>
    <body>
        <div class="box"></div>
    </body>
    <script>
        
        // 如何获取事件对象?
        // 给事件处理函数一个形参;
        var obox = document.querySelector(".box") 
    
        // obox.onclick = function(abc){
        //     console.log(abc)
        // }
        // obox.onclick = function(){
        //     console.log(window.event)  //可以在ie使用;
        // }
    
        // 解决兼容
    
        obox.onclick = function(eve){
            var e = eve || window.event;
            console.log(e);//通过event获得一个对象
            
        }
    
        
    </script>
    </html>

    三、阻止事件冒泡的方法和它的兼容问题以及解决方式

    方 法 一:eve.stopPropagation(); 主要针对正常浏览器

    方 法 二:eve.cancelBubble = true; 在IE浏览器中使用

    解决兼容问题的方式:

    function stopBubble(e){
            if(e.stopPropagation){
                e.stopPropagation();
            }else{
                e.cancelBubble = true;
            }
        }

     案例:

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
        <style>
            .box1 {
                 400px;
                height: 400px;
                background: red
            }
    
            .box2 {
                 300px;
                height: 300px;
                background: blue
            }
    
            .box3 {
                 200px;
                height: 200px;
                background: green
            }
        </style>
    </head>
    
    <body>
        <div class="box1">
            <div class="box2">
                <div class="box3"></div>
            </div>
        </div>
    </body>
    <script>
        // 事件冒泡
        // 当触发某个元素的某个事件时,它会先触发自己的对应事件,然后,“依次向上”触发所有父级的“相同事件”,如果中间有父级没有“相同事件”,继续向上触发
        // 事件流:事件执行顺序我们叫他事件流。
        // 事件流中事件冒泡的由来:IE公司认为,如果你面前有个靶子,你的飞镖射中了其中一环,并不仅仅是只对这一环产生了操作,而是对整个靶子都产生了操作。
    
        // 所以,当 最里面 的元素触发了事件的时候,会依次向上触发所有元素的相同事件(从触发事件的元素开始一直向上触发),但是事件冒泡对我们几乎没有任何好处,
        // 所以我们需要阻止事件冒泡。
    
        //阻止事件冒泡的两种方法
        // eve.stopPropagation();            
        // eve.cancelBubble = true;        //兼容IE
    
        // 解决兼容问题:封装一个函数
        function stopBubble(e){
            if(e.stopPropagation){
                e.stopPropagation();
            }else{
                e.cancelBubble = true;
            }
        }
    
        var obox1 = document.querySelector(".box1");
        var obox2 = document.querySelector(".box2");
        var obox3 = document.querySelector(".box3");
    
        obox1.onclick = function(eve){
            var e = eve || window.event;
            stopBubble(e);
            alert("red");
        }
    
        obox2.onclick = function(eve){
            var e = eve || window.event;
            stopBubble(e);
            alert("blue");
        }
    
        obox3.onclick = function(eve){
            var e = eve || window.event;
            stopBubble(e);
            alert("green");
        }
    
    </script>
    </html>

    四、键盘事件的兼容问题以及解决方式

    解决兼容问题的方式:
    var e = eve || window.event;
    var code = eve.keyCode || window.which;

    案例:

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
        <style>
            .box {
                 100px;
                height: 100px;
                background: red;
                position: absolute;
                left: 0;
                top: 0;
            }
        </style>
    </head>
    <body>
        <div class="box"></div>
    </body>
    <script>
        // 和鼠标事件一样,键盘事件也存在兼容;
        // var e = eve || window.event;
        // var code = e.keyCode || e.which;
    
        // 案例:通过键盘上下左右,控制页面中的元素位置移动
    
        var obox = document.querySelector("div");
        // 这个div并没有焦点;所以:
        //先创一个事件对象;
        document.onkeydown = function(eve){
            var e = eve || window.event;
            var code = eve.keyCode || window.which;
    
            // 这里通过选择语句中的switch();
            switch(code){
                // 获取元素与父元素之间的偏移距离;用offsetLeft/offsetTop;
                case 37 : //左键
                obox.style.left = obox.offsetLeft-10 + "px";break;
                case 38 : //上键
                obox.style.top = obox.offsetTop-10 + "px";break;
                case 39 : //右键
                obox.style.left = obox.offsetLeft+10 + "px";break; // 向上向右就是+10;
                case 40 : //下键
                obox.style.top = obox.offsetTop+10 + "px";break;
            }
        }
    </script>
    </html>

    五、阻止默认事件的方法和它的兼容问题以及解决方式

    方 法 一:

    e.preventDefault();
    window.event.returnValue = false;

    方 法 二:

    在事件处理函数的最后加上 return false;
     
    解决兼容问题的方式:
    function stopDefault(e){
        if(e.preventDefault){
            e.preventDefault()
        }else{
            e.returnValue = false;
        }
    }

    案例:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
        <style>
            .box {
                 120px;
                height: 220px;
                background: #fff;
                border: 1px solid #000;
                position: absolute;
                left: 0;
                right: 0;
                display: none;
            }
            .box ul {
                margin: 0;
            }
        </style>
    </head>
    <body>
        <div class="box">
            <ul>
                <li>刷新</li>
                <li>复制</li>
                <li>粘贴</li>
                <li>剪切</li>
                <li>删除</li>
            </ul>
        </div>
    </body>
    <script>
        // 浏览器默认行为;
        // 默认事件:就是浏览器自己触发的事件。比如:a链接的跳转,form提交时的跳转,鼠标右键菜单。
        // 当触发鼠标的右键事件时,会弹出右键菜单,这就是默认事件情况之一;
    
        // 如何阻止默认事件两种方法
        //一、解决兼容
        // e.preventDefault()();
        // window.event.returnValue = false;
    
        // 二、
        // 在事件处理函数的最后加上 return false;
    
    
        // 案例:自定义右键菜单
    
        // oncontextmenu 鼠标点击右键;
        var obox = document.querySelector(".box");
        // 给阻止事件的方法封装为一个函数
        function stopDefault(e){
            if(e.preventDefault){
                e.preventDefault();
            }else{
                e.returnValue = false;
            }
        }
    
        document.oncontextmenu = function(eve){
            var e = eve || window.event;
            
            obox.style.display = "block";
            // 阻止默认设置
            // stopDefault(e);
        
            obox.style.left = e.offsetX + "px";
            obox.style.top = e.offsetY + "px";
            //return false 也可以阻止默认事件:必须函数里的最后一位
            return false;
    
        }
    
        document.onclick = function(){
            obox.style.display = "none";
        }
    
        function stopDefault(e){
            if(e.preventDefault){
                e.preventDefault();
            }else{
                e.returnValue = false;
            }
        }
    </script>
    </html>

    六、事件监听器

    事件触发阶段主要由于事件流:DOM0级事件处理阶段和DOM2级事件处理;
     
        DOM0级事件处理,是一种赋值方式,是被所有浏览器所支持的,简单易懂容易操作;
            元素.onclick = function(){}
     
        DOM2级事件处理是所有DOM节点中的方法,可以重复绑定,但是浏览器兼容存在问题;
     
        非IE下:(这里的事件名不带on),第三个参数表示是在捕获阶段还是冒泡阶段。可以重复绑定事件,执行顺序按照绑定顺序来执行。
     
        oDiv.addEventListener('click',fn,false);
        oDiv.removeEventListener('click',fn ,false);
     
        IE下:
     
        只有冒泡阶段,所以没有第三个参数;(这里的事件名需要加on)
        oDiv.attachEvent();
        oDiv.detachEvent() ;
     
    解决兼容问题的方式:
    1.封装成对象的方式
        var EventUtil={
            addHandler:function(DOM,EventType,fn){
                if(DOM.addEventListener){
                    DOM.addEventListener(EventType,fn,false);
                }else if(DOM.attachEvent){
                    DOM.attachEvent('on'+EventType,fn)
                }else{
                    DOM['on'+EventType]=fn
                }
            },
            removeHandler:function(DOM,EventType,fn){
                if(DOM.removeEventListener){
                    DOM.removeEventListener(EventType,fn,false)
                }else if(DOM.detachEvent){
                    DOM.detachEvent('on'+EventType,fn)
                }else{
                    DOM['on'+EventType]=null;
                }
            }
        }
    
    
    2.封装成两个函数的方式
        function addEvent(obj,inci,back){
            if(obj.addEventListener){
                obj.addEventListener(inci,back);
            }else if(obj.attachEvent){
                obj.attachEvent("on" + inci,back);
            }else{
                obj["on"+inci] = back;
            }
        }
              
        function removeEvent(obj,inci,back){
            if(obj.removeEventListener){
                obj.removeEventListener(inci,back,false);
            }else if(obj.detachEvent){
                obj.detachEvent("on" + inci,back);
            }else{
                obj["on"+inci] = null;
            }
        }

    案例:

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
        <style>
            .box {
                 100px;
                height: 100px;
                background: red;
            }
        </style>
    </head>
    
    <body>
        <div class="box"></div>
    </body>
    <script>
        var obox = document.querySelector(".box");
        //  事件触发阶段主要由于事件流:DOM0级事件处理阶段和DOM2级事件处理;
        // DOM0级事件处理,是一种赋值方式,是被所有浏览器所支持的,简单易懂容易操作;
        // 元素.onclick = function(){}
    
        // 赋值式绑定 (DOM0级事件处理阶段)
        // obox.onclick = function(){
        //     console.log(1);   
        // }
    
        // obox.onclick = function(){
        //     console.log(2);   
        // }
        // 当你点击元素时,只能获取1,2中的一个值;
        // 删除赋值式事件绑定;
        // obox.onclick = null;
        // 特点:常用,没有兼容,简单
    
        
        // 监听式绑定(DOM2级事件处理):可以重复绑定;
        // 非IE下:(这里的事件名不带on),第三个参数表示是在捕获阶段还是冒泡阶段。可以重复绑定事件,执行顺序按照绑定顺序来执行。
    
        
        // EventTarget.addEventListener() 方法将指定的监听器注册到 EventTarget 上,
        // 当该对象触发指定的事件时,指定的回调函数就会被执行。
        // oDiv.addEventListener('click', fn, false);
        // 第一个参数表示:表示监听事件类型的 字符串 。
       
        // 第二个参数表示:当所监听的事件类型触发时,会接收到一个事件通知(实现了 Event 接口的对象)对象。listener 必须是一个实现了 EventListener 接口的对象,或者是一个函数。
        
        // 第三个参数表示:当第三个参数(设为true) 时,沿着DOM树向上冒泡的事件,不会触发listener。当一个元素嵌套了另一个元素,
        // 并且两个元素都对同一事件注册了一个处理函数时,所发生的事件 冒泡和事件捕获 是两种不同的事件传播方式。事件传播模式决定了元素以哪个顺序接收事件。
        // 第三个参数可写可不写;
    
        // oDiv.removeEventListener('click', fn, false);
        // 删除使用 EventTarget.addEventListener() 方法添加的事件。
        
        // IE下:
    
        // 只有冒泡阶段, 所以没有第三个参数;(这里的事件名需要加on)
        // oDiv.attachEvent() ;
        // oDiv.detachEvent();
    
        // 冒泡:从下往上(从里往外)
        // 捕获:从上往下(从外往内)
    
        // 如何解决兼容问题
        // 将对象放入到括号内
        // cb表示事件处理函数
        function removeEvent(ele,type,cb){
            if(ele.removeEventListener){
                ele.removeEventListener(type,cb)
            }else if(ele.detachEvent){
                ele.detachEvent("on"+type,cb)
            }else{
                ele["on"+type] = null;
            }
        }
    
        function addEvent(ele,type,cb){
            if(ele.addEventListener){
                ele.addEventListener(type,cb)
            }else if(ele.attachEvent){
                ele.attachEvent("on"+type,cb)
            }else{
                ele["on"+type] = cb;
            }
        }
    
        
    
    
    
    </script>
    
    </html>

    七、事件委托中事件源的兼容问题

    解决兼容问题的方式:
     
    var t = e.target || e.srcElement; 

    案例:

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
        <style>
            ul {
                background: #ccc
            }
    
            li {
                padding: 10px 0;
                margin: 10px 0;
                background: red
            }
        </style>
    </head>
    
    <body>
        <ul>
            <li>link1</li>
            <li abc="l">link2</li>
            <li abc="l">link3</li>
            <li abc="l">link4</li>
            <li>link5</li>
        </ul>
    </body>
    <script>
        var ali = document.querySelectorAll("ul li");
    
        var oul = document.querySelector("ul")
        oul.onclick = function(eve){
            var e = eve || window.event;
    
            var t = e.target || e.srcElement;   // 也是一种兼容
    
            if(t.getAttribute("abc") == "l"){
                console.log(e.target.innerHTML)
            }
            
        }
    </script>
    </html>
  • 相关阅读:
    Ajax核心对象和AjaxPro框架
    ASP.NET XML与JSON
    jQuery中Ajax的应用
    jQuery中操作表单与表格
    IOS 非常流畅的滑动tableView
    提高自己应用性能的总结架构篇
    LazyCode 自己开源的一个类库
    iOS 自己写的对话框中加入三个输入框
    icmp 流量抓取 转发 代理(2)
    sublime text ctags插件使用
  • 原文地址:https://www.cnblogs.com/yangbodeboke/p/11437559.html
Copyright © 2011-2022 走看看