【JS封装-兼容IE(较旧版本如IE8及以下)】强化编程实践:精选JavaScript函数封装集锦-添加Event监听、获取非行间样式、支持跨浏览器的classList操作等IE低版本兼容

14 篇文章 0 订阅
10 篇文章 0 订阅

目录

添加Event监听

获取非行间样式

JSON.parse与JSON.stringify

querySelector与querySelectorAll的兼容

支持跨浏览器的classList操作

兼容性处理console.log

兼容性处理forEach方法

Promise的兼容性处理

Fetch API的兼容性处理


添加Event监听

IE8及以下版本不支持addEventListener,需要使用attachEvent

function addEvent(elem, event, fn) {
    if (elem.addEventListener) {
        elem.addEventListener(event, fn, false);
    } else if (elem.attachEvent) {
        elem.attachEvent("on" + event, function() {
            // 设置this指向正确
            return(fn.call(elem, window.event));   
        });
    }
}

使用示例:

var btn = document.getElementById('myButton');
addEvent(btn, 'click', function(e) {
    alert('按钮被点击了!');
});

获取非行间样式

IE获取计算后的样式需要使用currentStyle,而其他现代浏览器使用getComputedStyle

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

使用示例:

var element = document.getElementById('someElement');
var color = getStyle(element, 'color');
console.log(color);

JSON.parse与JSON.stringify

IE7及以下不支持这两个方法。

if (!window.JSON) {
    window.JSON = {
        parse: function(str) {
            return new Function('return ' + str)();
        },
        stringify: function(obj) {
            var arr = [];
            for (var prop in obj) {
                if (Object.prototype.hasOwnProperty.call(obj, prop)) {
                    arr.push(prop + ':' + obj[prop]);
                }
            }
            return '{' + arr.join(',') + '}';
        }
    };
}

使用示例:

var jsonString = '{"name":"John","age":30}';
var obj = JSON.parse(jsonString);
console.log(obj.name); // 输出: John

var objToSerialize = {name: "Alice", age: 25};
var serializedString = JSON.stringify(objToSerialize);
console.log(serializedString); // 输出: {"name":"Alice","age":25}

querySelector与querySelectorAll的兼容

IE8及以下不支持这两个方法。

if (!document.querySelector) {
    document.querySelector = function(selector) {
        var elements = document.querySelectorAll(selector);
        return elements.length ? elements[0] : null;
    };
}

if (!document.querySelectorAll) {
    document.querySelectorAll = function(selector) {
        var styleSheet = document.createStyleSheet();
        styleSheet.addRule(selector, "foo:bar");
        var elements = document.all.tags("foo");
        styleSheet.removeRule(0);
        return elements;
    };
}

使用示例:

var firstDiv = document.querySelector('div');
console.log(firstDiv);

var allDivs = document.querySelectorAll('div');
allDivs.forEach(function(div) {
    console.log(div);
});

支持跨浏览器的classList操作

IE9及以下版本不支持element.classList,可以进行如下封装以提供类似功能。

function classListSupport(element) {
    if ('classList' in document.documentElement) {
        return function(action, className) {
            if (action === 'add') {
                element.classList.add(className);
            } else if (action === 'remove') {
                element.classList.remove(className);
            } else if (action === 'toggle') {
                element.classList.toggle(className);
            } else if (action === 'contains') {
                return element.classList.contains(className);
            }
        };
    } else {
        var classes = element.className.split(' ');
        return function(action, className) {
            switch (action) {
                case 'add':
                    if(classes.indexOf(className) === -1) {
                        classes.push(className);
                        element.className = classes.join(' ');
                    }
                    break;
                case 'remove':
                    var index = classes.indexOf(className);
                    if(index !== -1) {
                        classes.splice(index, 1);
                        element.className = classes.join(' ');
                    }
                    break;
                case 'toggle':
                    var contains = classes.indexOf(className) !== -1;
                    if(contains) {
                        this.remove(className);
                    } else {
                        this.add(className);
                    }
                    break;
                case 'contains':
                    return classes.indexOf(className) !== -1;
            }
        };
    }
}

// 使用示例:
var myElement = document.getElementById('myElement');
var classHandler = classListSupport(myElement);

classHandler('add', 'newClass'); // 添加类
classHandler('remove', 'oldClass'); // 移除类
console.log(classHandler('contains', 'newClass')); // 检查是否包含类
classHandler('toggle', 'active'); // 切换类

兼容性处理console.log

在IE中,如果开发者工具未打开,直接使用console.log可能会导致错误。可以通过以下方式避免:

if (!window.console) {
    window.console = {};
}
if (!window.console.log) {
    window.console.log = function(msg) {
        if (typeof msg === "object") {
            msg = JSON.stringify(msg);
        }
        alert(msg);
    };
}

使用示例:

console.log("这是一个消息");
console.log({key: "value"}); // 对象会自动转换为JSON字符串

兼容性处理forEach方法

对于数组的forEach方法,IE8及以下版本并不支持。可以自定义一个兼容版本:

if (!Array.prototype.forEach) {
    Array.prototype.forEach = function(callback, thisArg) {
        var T, k;
        if (this == null) {
            throw new TypeError('this is null or not defined');
        }
        var O = Object(this);
        var len = O.length >>> 0;
        if (typeof callback !== 'function') {
            throw new TypeError(callback + ' is not a function');
        }
        if (arguments.length > 1) {
            T = thisArg;
        }
        k = 0;
        while (k < len) {
            var kValue;
            if (k in O) {
                kValue = O[k];
                callback.call(T, kValue, k, O);
            }
            k++;
        }
    };
}

使用示例:

var arr = [1, 2, 3];
arr.forEach(function(item, index, array) {
    console.log(item);
});

Promise的兼容性处理

IE11开始才支持Promise,对于旧版IE,可以使用polyfill库,如es6-promise。

安装es6-promise:

npm install es6-promise --save

然后,在你的主入口文件引入并设置为全局:

import 'es6-promise/auto';

或者直接在HTML中通过CDN引入:

<script src="https://cdn.jsdelivr.net/npm/es6-promise@4/dist/es6-promise.auto.min.js"></script>

使用示例:

new Promise((resolve, reject) => {
    setTimeout(() => resolve('成功'), 1000);
}).then(value => console.log(value));

Fetch API的兼容性处理

IE不支持Fetch API,可以使用fetch-ie8或者whatwg-fetch作为polyfill。

安装whatwg-fetch:

npm install whatwg-fetch --save

然后,在主入口文件引入:

import 'whatwg-fetch';

或在HTML中通过CDN引入:

<script src="https://cdnjs.cloudflare.com/ajax/libs/fetch/2.0.4/fetch.min.js"></script>

使用示例:

fetch('https://api.example.com/data')
    .then(response => response.json())
    .then(data => console.log(data))
    .catch(error => console.error('Error:', error));

  • 11
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

何遇mirror

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值