我有一个脚本,它遍历数组中传递的值,并检查浏览器是否本机支持这些项。这在Chrome,Edge,FireFox和Safari中运行良好,但IE11及更早版本(真正需要它的浏览器)会引发错误。数组值是字符串(如下所示)但由于某种原因,IE11将它们视为对象,这意味着当我尝试检查a时。在字符串中,IE错误输出。
我试过转换数组项toString
,但这只会导致object object
或object undefined
。
我已经设置了一个CodePen,其中包含完整的代码集:https://codepen.io/willstocks_tech/pen/YBEzLW?editors=1012
可以在IE中使用的版本是:https://s.codepen.io/willstocks_tech/debug/YBEzLW/mWAoNxdogGvr(虽然这可能会过期!)
//https://github.com/willstocks-tech/dynamically-polyfill-features-for-a-script/releases/
dynamicPolyfill(
['IntersectionObserver', 'IntersectionObserverEntry', 'Object.assign', 'Array.copyWithin']
,'https://cdn.jsdelivr.net/npm/[email protected]/dist/quicklink.umd.js'
,'quicklink()'
)
function dynamicPolyfill(tocheck, scriptToPolyfill, functionToRunonLoad) {
if(typeof Promise !== "undefined"){
var checkPromises = [];
if(Array.isArray(tocheck)) {
tocheck.forEach(
function(tocheck){
checkPromises.push(checking(tocheck))
}
)
} else {
checkPromises.push(checking(tocheck))
}
checkPromises = checkPromises.filter(function(p){return p !== undefined}).join(' ');
loadPolyfill(checkPromises, scriptToPolyfill, functionToRunonLoad)
} else {
promiFill(tocheck, scriptToPolyfill, functionToRunonLoad);
}
}
function promiFill(tocheck, scriptToPolyfill, functionToRunonLoad){
var promPolyfill = document.createElement('script');
promPolyfill.src = ('https://polyfill.io/v3/polyfill.min.js?features=Promise');
document.body.appendChild(promPolyfill);
promPolyfill.onerror = function(response) {
console.error("Polyfilling promise failed", response);
}
promPolyfill.onload = function(tocheck, scriptToPolyfill, functionToRunonLoad) {
dynamicPolyfill(tocheck, scriptToPolyfill, functionToRunonLoad);
}
}
function checking(check){
var splitChars = '.';
if ((check in window) != true || (check in this) != true) {
if (check.indexOf(splitChars) >= 1) {
var split = check.split('.');
var firstWord = window[split[0]];
var lastWord = new Object(split[split.length - 1]);
if (lastWord in firstWord != true && lastWord in firstWord.prototype != true) {
return check;
}
} else {
return check;
}
}
}
function loadPolyfill(url, scriptToPolyfill, functionToRunonLoad) {
if(url !== "") {
var polyfill = document.createElement('script');
polyfill.src = ('https://polyfill.io/v3/polyfill.min.js?features='+encodeURIComponent(url));
document.body.appendChild(polyfill);
polyfill.onerror = function(response) {
console.error("Loading the polyfill(s) failed!", response);
}
polyfill.onload = function() {
loadMyScript(scriptToPolyfill, functionToRunonLoad)
}
} else {
loadMyScript(scriptToPolyfill, functionToRunonLoad)
}
}
function loadMyScript(url, functionToRunonLoad) {
if(Array.isArray(url)) {
var promises = [];
url.forEach(
function(url){
promises.push(nonblankURL(url));
}
);
Promise.all(promises)
.then(
function() {
initialiseMyScript(functionToRunonLoad)
}
).catch(function(error){return error})
} else if (!Array.isArray(url) && url !== null && url !== '') {
nonblankURL(url)
.then(
function() {
initialiseMyScript(functionToRunonLoad)
}
).catch(function(error){return error})
} else {
initialiseMyScript(functionToRunonLoad)
}
}
function nonblankURL(uri){
return new Promise(
function(resolve, reject) {
var thescript = document.createElement('script');
thescript.src = encodeURI(uri);
document.body.appendChild(thescript);
thescript.onerror = function(response) {
return reject("Loading the script failed!", response);
}
thescript.onload = function() {
return resolve(uri);
}
}
)
}
function initialiseMyScript(functionToRunonLoad) {
if(Array.isArray(functionToRunonLoad)) {
functionToRunonLoad.forEach(
function(functionToRunonLoad){
initScript(functionToRunonLoad)
}
)
} else {
initScript(functionToRunonLoad)
}
function initScript(fn) {
try {
window[fn];
} catch(err) {
console.error('There was an error: ', err, err.name, err.stack);
}
}
}
所有其他浏览器似乎处理这个很好,但IE11和更旧版本抛出以下错误:SCRIPT438: Object doesn't support property or method 'indexOf'
我不能为我的生活工作如何让它在IE中工作,同时也在所有其他浏览器中工作!
你可以在IE11调试器中看到tocheck
在那一点上是一个Event对象(显然没有indexOf
)。那是因为这段代码:
promPolyfill.onload = function(tocheck, scriptToPolyfill, functionToRunonLoad) {
dynamicPolyfill(tocheck, scriptToPolyfill, functionToRunonLoad);
}
DOM事件处理程序接收的第一个也是唯一的参数是一个事件对象,但是你接受它为tocheck
然后用该事件调用dynamicPolyfill
。
你可能意味着:
promPolyfill.onload = function() {
dynamicPolyfill(tocheck, scriptToPolyfill, functionToRunonLoad);
};
或类似的。无论如何,问题是在indexOf
对象上调用Event
。