IE11对象不支持属性或方法'indexOf'(但它不是对象,可以在其他浏览器中使用)

问题描述 投票:-1回答:1

我有一个脚本,它遍历数组中传递的值,并检查浏览器是否本机支持这些项。这在Chrome,Edge,FireFox和Safari中运行良好,但IE11及更早版本(真正需要它的浏览器)会引发错误。数组值是字符串(如下所示)但由于某种原因,IE11将它们视为对象,这意味着当我尝试检查a时。在字符串中,IE错误输出。

我试过转换数组项toString,但这只会导致object objectobject 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中工作,同时也在所有其他浏览器中工作!

javascript internet-explorer cross-browser legacy
1个回答
0
投票

你可以在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

© www.soinside.com 2019 - 2024. All rights reserved.