“对象不支持此属性或方法"IE10/11 [英] "Object doesn't support this property or method" IE10/11
问题描述
随着 ES6 的普及,我渴望放弃 jQuery 并使用原生 JS 来构建我的网站,以保持它们的快速和轻量.也是为了提高我的 JS 技能,因为我是直接使用 jQuery 的人之一.
With ES6 taking ahold, I'm eager to drop jQuery and use native JS for my website builds keeping them quick and lightweight. Also to improve my JS skills as I'm one of those whose jumped straight in with jQuery.
我正在构建一个很小的库,以便在函数中使用更常用的 javascript 以保持文件较小.
I'm building a tiny tiny library to make the more common used javascript in a function to keep the files small.
function $(elm) {
var elm = document.querySelectorAll(elm);
this.forEach = function(f) {
[].forEach.call(elm, f);
}
return elm;
}
function slider() {
$(".slider").forEach(function() {
alert("Hello");
});
}
slider();
这在 Chrome 等中效果很好.但在 IE10/11 中我收到错误
This works great in Chrome etc.. but in IE10/11 I'm getting the error
对象不支持forEach"这个属性或方法
Object doesn't support this property or method "forEach"
指的是 $(".slider").forEach
referring to the $(".slider").forEach
有什么想法吗?
推荐答案
您将 forEach
添加到 window
对象,而不是添加到您返回的对象;您将 $
作为函数调用,而不是构造函数.由于您使用的是松散模式(显然),函数调用中的 this
是对全局对象的引用(在浏览器上也可以作为 window
访问).您从 querySelectorAll
返回的集合保持不变.
You're adding forEach
to the window
object, not to the object you return; you're calling $
as a function, not a constructor. Since you're using loose mode (apparently), this
within the function call is a reference to the global object (also accessible as window
on browsers). You're returning the collection from querySelectorAll
unchanged.
它在 Chrome 上工作的原因是 querySelectorAll
返回的集合有自己的 forEach
(这是最近添加的).
The reason it works on Chrome is that the collection returned by querySelectorAll
has its own forEach
(this is a fairly recent addition).
为此,有四个选项:
返回一个对象并将
forEach
添加到它,将元素从 QSA 集合复制到该对象.例如:
Return an object and add
forEach
to it, copying the elements from the QSA collection to that object. E.g.:
function $(selector) {
const result = Array.from(document.querySelectorAll(selector));
result.forEach = Array.prototype.forEach;
// Perhaps map, filter, etc.; add in a loop?
return result;
}
或者在 ES5 中:
var $ = (function() {
var methods = Array.prototype;
function $(selector) {
var result = methods.slice.call(document.querySelectorAll(selector));
result.forEach = methods.forEach;
// Perhaps map, filter, etc.; add in a loop?
return result;
}
return $;
})();
将 forEach
添加到 NodeList
原型中(如果它尚不存在)并直接在 querySelectorAll 的集合上使用
forEach
代码>.例如:
Add forEach
to the NodeList
prototype if it's not already there and use forEach
directly on the collection from querySelectorAll
. For instance:
if (typeof NodeList !== "undefined" &&
NodeList.prototype &&
!NodeList.prototype.forEach) {
// Yes, direct assignment is fine here, no need for `Object.defineProperty`
NodeList.prototype.forEach = Array.prototype.forEach;
}
(不需要上面的 Object.defineProperty
,enumerable
[令人惊讶地],configurable
和 writable
是所有 true
在 Chrome 和 Firefox 上都为它,所以我们可以像上面那样直接赋值.)
(No need for Object.defineProperty
above, enumerable
[surprisingly], configurable
, and writable
are all true
for it on Chrome and Firefox, so we can just do direct assignment as above.)
...然后当然你的 $
就变成了
...and then of course your $
becomes nothing more than
function $(selector) {
return document.querySelectorAll(selector);
}
(首先.如果您想添加更多功能,您可能想走#1 的方式.)
(To start with. If you wanted to add more features, you'd probably want to go the way of #1.)
返回一个数组:
function $(selector) {
return Array.from(document.querySelectorAll(selector));
}
或者在 ES5 中:
function $(selector) {
return Array.prototype.slice.call(document.querySelectorAll(selector));
}
子类 Array
(在 ES2015 之前的 JavaScript 引擎上无法完美填充),因此您可以在 Array
的功能之上添加自己的功能:
Subclass Array
(which cannot be perfectly polyfilled on pre-ES2015 JavaScript engines) so you can add your own features on top of Array
's features:
class MyThingy extends Array {
// Perhaps further methods here
}
function $(selector) {
return MyThingy.from(document.querySelectorAll(selector));
}
此处没有 ES5 选项,您至少需要进行转译和 polyfill.
No ES5 option here, you'd need to at least transpile and polyfill.
如果您要添加 Array
提供的功能之外的功能,我非常喜欢 #4,除了可用的 polyfilling 只是非常"好.它可能足以满足您的目的.
If you're going to add features beyond those provided by Array
, I quite like #4 other than the polyfilling available only being "so" good. It may well be sufficient for your purposes.
这篇关于“对象不支持此属性或方法"IE10/11的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!