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

时间:2019-02-19 11:53:18

标签: javascript internet-explorer cross-browser legacy

我有一个脚本,该脚本遍历数组中传递的值,并检查浏览器是否原生支持这些项目。这在Chrome,Edge,FireFox和Safari中可以正常工作,但IE11和更早的版本(确实需要此功能的浏览器才能运行)会引发错误。 数组值是字符串(如下所示),但是由于某种原因,IE11将它们视为对象,这意味着当我尝试检查时。在字符串中,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/quicklink@1.0.0/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中使其同时在所有其他浏览器中工作!

1 个答案:

答案 0 :(得分: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