IE11 对象不支持 属性 或方法 'indexOf'(但它不是一个对象并且在其他浏览器中工作)
IE11 Object doesn't support property or method 'indexOf' (but it's not an object and works in other browsers)
我有一个脚本可以遍历数组中传递的值,并检查浏览器是否原生支持这些项目。这在 Chrome、Edge、FireFox 和 Safari 中工作正常,但 IE11 和更早版本(确实 需要它才能工作的浏览器)会抛出错误。
数组值是字符串(如下所示)但出于某种原因,IE11 将它们视为对象,这意味着当我尝试检查一个 .在字符串中,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/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 中工作,但同时在所有其他浏览器中也能工作!
你可以在IE11调试器中看到tocheck
此时是一个Event对象(显然没有indexOf
)。那是因为这段代码:
promPolyfill.onload = function(tocheck, scriptToPolyfill, functionToRunonLoad) {
dynamicPolyfill(tocheck, scriptToPolyfill, functionToRunonLoad);
}
DOM 事件处理程序接收的第一个也是唯一一个参数是一个事件对象,但您将其作为 tocheck
接受,然后使用该事件调用 dynamicPolyfill
。
您的意思可能是:
promPolyfill.onload = function() {
dynamicPolyfill(tocheck, scriptToPolyfill, functionToRunonLoad);
};
或类似的。无论如何,问题是在 Event
对象上调用 indexOf
。
我有一个脚本可以遍历数组中传递的值,并检查浏览器是否原生支持这些项目。这在 Chrome、Edge、FireFox 和 Safari 中工作正常,但 IE11 和更早版本(确实 需要它才能工作的浏览器)会抛出错误。 数组值是字符串(如下所示)但出于某种原因,IE11 将它们视为对象,这意味着当我尝试检查一个 .在字符串中,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/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 中工作,但同时在所有其他浏览器中也能工作!
你可以在IE11调试器中看到tocheck
此时是一个Event对象(显然没有indexOf
)。那是因为这段代码:
promPolyfill.onload = function(tocheck, scriptToPolyfill, functionToRunonLoad) {
dynamicPolyfill(tocheck, scriptToPolyfill, functionToRunonLoad);
}
DOM 事件处理程序接收的第一个也是唯一一个参数是一个事件对象,但您将其作为 tocheck
接受,然后使用该事件调用 dynamicPolyfill
。
您的意思可能是:
promPolyfill.onload = function() {
dynamicPolyfill(tocheck, scriptToPolyfill, functionToRunonLoad);
};
或类似的。无论如何,问题是在 Event
对象上调用 indexOf
。