JS 多浏览器兼容

/ 15评论 / 294阅读 / 0点赞

前言

JS获取浏览器版本

// 获取指定浏览器的主版本号,如果不是指定浏览器,则返回0
        var getIEVersion = function () {
            var match = navigator.userAgent.match(/(?:MSIE |Trident\/.*; rv:)(\d+)/);
            return (match && match.length >= 2) ? parseInt(match[1]) : 0;
        }
        var getFireFoxVersion = function () {
            var match = navigator.userAgent.match(new RegExp('Firefox/([^)]+)'));
            return (match && match.length >= 2) ? parseInt(match[1]) : 0;
        }
        var getChromeVersion = function () {
            var relist = navigator.userAgent.match(/Chrome\/([\d]+)/);
            if (null == relist || relist.length <= 1) {
                return 0;
            }
            return parseInt(relist[1]);
        }

缺少原生 JS 的内置函数或类实现

document.getElementsByClassName

        if (!document.getElementsByClassName) {
            document.getElementsByClassName = function (className, element) {
                var children = (element || document).getElementsByTagName('*');
                var elements = new Array();
                for (var i = 0; i < children.length; i++) {
                    var child = children[i];
                    var classNames = child.className.split(' ');
                    for (var j = 0; j < classNames.length; j++) {
                        if (classNames[j] == className) {
                            elements.push(child);
                            break;
                        }
                    }
                }
                return elements;
            };
        }

Function.prototype.bind

        if (!Function.prototype.bind) {
            // 兼容 ie,缺失 bind
            Function.prototype.bind = function (oThis) {
                if (typeof this !== "function") {
                    // closest thing possible to the ECMAScript 5 internal IsCallable function
                    throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
                }

                var aArgs = Array.prototype.slice.call(arguments, 1);
                var fToBind = this;
                var fNOP = function () { };
                var fBound = function () {
                    return fToBind.apply(
                        this instanceof fNOP && oThis
                            ? this
                            : oThis,
                        aArgs.concat(Array.prototype.slice.call(arguments))
                    );
                };

                if (this.prototype) {
                    fNOP.prototype = this.prototype;
                }
                fBound.prototype = new fNOP();
                return fBound;
            };
        }

window.atob

        if (!window.atob) {
            window.atob = function (str) {
                var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
                var output = "";
                var len = str.length;
                if (str.charAt(len - 1) === "=") {
                    output += String.fromCharCode((parseInt(str.slice(len - 2, len), 16) << 2));
                } else if (str.charAt(len - 2) === "=") {
                    output += String.fromCharCode((parseInt(str.slice(len - 1), 16) << 4));
                } else {
                    for (var i = 0; i < len; i += 4) {
                        var byte1 = chars.indexOf(str.charAt(i));
                        var byte2 = chars.indexOf(str.charAt(i + 1));
                        var triplet = ((byte1 << 2) | (byte2 >> 4)) & 255;
                        output += String.fromCharCode(triplet);
                        if (i + 2 < len) {
                            var byte3 = chars.indexOf(str.charAt(i + 2));
                            if (byte3 !== 64) { // '=' is 64 in ASCII
                                triplet = (((byte2 & 15) << 4) | (byte3 >> 2)) & 255;
                                output += String.fromCharCode(triplet);
                            }
                        }
                        if (i + 3 < len) {
                            var byte4 = chars.indexOf(str.charAt(i + 3));
                            if (byte4 !== 64) {
                                triplet = (((byte3 & 3) << 6) | byte4) & 255;
                                output += String.fromCharCode(triplet);
                            }
                        }
                    }
                }
                return output;
            };
        }
        var atob = window.atob;

window.btoa

        if (!window.btoa) {
            window.btoa = function (str) {
                var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
                var output = '';
                var i = 0;

                while (i < str.length) {
                    var byte1 = str.charCodeAt(i++);
                    var byte2 = str.charCodeAt(i++);
                    var byte3 = str.charCodeAt(i++);
                    var enc1 = byte1 >> 2;
                    var enc2 = ((byte1 & 3) << 4) | (byte2 >> 4);
                    var enc3 = ((byte2 & 15) << 2) | (byte3 >> 6);
                    var enc4 = byte3 & 63;

                    if (isNaN(byte2)) {
                        enc3 = enc4 = 64;
                    } else if (isNaN(byte3)) {
                        enc4 = 64;
                    }

                    output += chars.charAt(enc1) + chars.charAt(enc2) + chars.charAt(enc3) + chars.charAt(enc4);
                }

                return output;
            };
        }
        var btoa = window.btoa;

问题

var func = function() {}
function hello () {}
// 应当: 
[1, 2, 3] 
{a: 1, b: 2}
var obj = {
    a : 1,
    b : 2
}
hello(
    a,
    b
) 

// 而不是 
[1, 2, 3, ] 
{ a: 1, b: 2, }
var obj = {
    a : 1,
    b : 2,    
}
hello(
    a,
    b,
) 
var data = 0; // ok
abc = 0;      // 不要,IE 部分版本不支持
let a = 0;    // 旧浏览器不支持
const b = 0;  // 旧浏览器不支持
// 假设由于浏览器缺少支持 Uint8Array,自定义实现了一个 Uint8Array
function Uint8Array() { ... }

var data = Uint8Array();
console.log(data[0]);     // 不建议
console.log(data.at(0));  // 建议使用
<!DOCTYPE html>
<html lang="zh">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>页面</title>
    <script>
        // 浏览器会认为字符串中的 </script> 是当前块的结束,然后后面的就有问题了。
        var data = "<script> console.log(hello); </script>";
        body.appendChild(data);
    </script>
</head>

<body>
</body>

</html>
var init_func = function () { ... }

init_func();

var createScriptBlock = function (func) {
    // - 直接写 script 标签会导致浏览器解析异常,因此拆分为多段字符串相加
    return "<" + "script" + ">" + "(" + func.toString() + ")();" + "</" + "script" + ">";
}
if (getIEVersion() > 0) {
    // - ie 使用整个覆盖页面后之前的页面 js 失效,因此需要在开头插入并再执行一次
    var headTagIndex = result.indexOf("</head>");
    if (headTagIndex < 0) {
        headTagIndex = 0;
    }
    result = result.slice(0, headTagIndex)
        + createScriptBlock(init_func)
        + result.slice(headTagIndex);
}
// 重新覆盖渲染页面内容
document.write(result);
document.close();
var obj = {
    data : "123"
};

obj.data = "456";
obj["data"] = "456";

Object.defineProperty(obj, 'data', {
    value: "456"
});

Object.defineProperty(obj, 'data', {
    get: function () {
        return "456";
    }
});
try {
    if (window.dispatchEvent && Event) {
        window.dispatchEvent(new Event('load'));
        return;
    }
} catch (e) { }
if (window.fireEvent) {
    window.fireEvent("onload");
}
  1. jalalive说道:

    Amazing Post, We waiting your next post, we we we we we are still waiting…

  2. jalalive说道:

    AMAZING POST BRO.!! WE WAIT YOUR NEW POST AHA AHA EHE EHE…!!!

  3. jalalive说道:

    AMAZING POSTT..!! CANT WAIT YOU NEXT POST.! Its goooddddddd

  4. net speed test说道:

    “Your writing style is engaging and clear, love it!”

  5. Amazing Post Broo!! Amazing Amazing!! Wait Your New Post Bro!!

  6. JalaLive说道:

    Amazing Post Broo!! Amazing Amazing!! Wait Your New Post Bro!!

  7. JalaLive说道:

    Amazing Post Broo!! Amazing Amazing!! Wait Your New Post Bro!!

  8. jalalive说道:

    Amazing Post!! Dont Forget Smile Every Day.!!

  9. JALALIVE说道:

    Amazing Post!! Dont Forget Smile Every Day.!!

  10. JALALIVE说道:

    Such a fantastic post! I really appreciate the depth of your research and how you present everything in such an easy-to-understand manner. It’s clear that you’re passionate about this topic, and it makes your content so enjoyable to read. Looking forward to your next post!

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注