我正在制作一个用于选择产品(颜色等)的脚本,它适用于除 Internet Explorer (11) 和 Edge 之外的所有浏览器。
我将每个参数的选择放在一个数组中,并使用 array.forEach() 方法对它们应用一个函数。
颜色参数示例:
var color_btns = document.querySelectorAll('#color > p');
color_btns.forEach(function(color) {
color.onclick = function () {
color_btns.forEach(function(element) {
if (element.classList.contains('selected')) {
element.classList.remove('selected');
}
});
color.classList.add('selected');
document.querySelector('#f_color').value = color.dataset.id;
};
});
我在 IE 和 Edge 的控制台中得到以下输出:
Object doesn't support property or method 'forEach'
经过查找问题,得知这个函数应该是supported by IE 9 and newer .我试图自己定义函数,但没有成功。当我记录该函数时,它被定义为一个函数(内部带有“[native code]”)。
我用 for 替换了每个 .forEach 并且它工作得很好,
forEach() 有特定用法吗?我认为它是 Array.prototype.forEach 并且最新版本的 IE(以及所有版本的 Edge)都有它......?
最佳答案
大多数 DOM 方法和集合属性实际上不是数组,它们是集合:
querySelectorAll返回静态 NodeList (调用时匹配元素的快照)。getElementsByTagName , getElementsByTagNameNS , getElementsByClassName , 和 children ParentNode 上的属性(property)(元素是父节点)返回 live HTMLCollection 实例(如果您更改 DOM,该更改会实时反射(reflect)在集合中)。getElementsByName返回一个live NodeList(不是快照)。NodeList 最近才得到 forEach(和 keys 以及其他几个数组方法)。 HTMLCollection 没有也不会;事实证明,添加它们会破坏网络上的太多代码。
不过,NodeList 和 HTMLCollection 都是可迭代,这意味着您可以使用 for-of 循环遍历它们>,通过 spread ([...theCollection]) 等将它们扩展成一个数组。但是如果您在 NodeList 没有 forEach,它可能太老了,无法拥有任何 ES2015+ 功能,例如 for-of 或迭代。
由于 NodeList 被指定为具有 forEach,您可以安全地对其进行 polyfill,而且真的很容易做到:
if (typeof NodeList !== "undefined" && NodeList.prototype && !NodeList.prototype.forEach) {
// Yes, there's really no need for `Object.defineProperty` here
NodeList.prototype.forEach = Array.prototype.forEach;
}
在这种情况下直接赋值是可以的,因为enumerable、configurable和writable都应该是true这是一个有值(value)的属性(property)。 (enumerable 为 true 令我感到惊讶,但这就是它在 Chrome/Chromium/Edge/Etc.、Firefox、旧版 Legacy Edge 和 Safari 上的原生定义)。
在你自己的代码中,如果你愿意,你也可以使用 HTMLCollection 来做到这一点,只是要注意,如果你使用一些旧的 DOM 库,比如 MooTools 或 YUI 或类似的,它们可能是如果将 forEach 添加到 HTMLCollection 会感到困惑。
正如我之前所说,NodeList 和 HTMLCollection 都被指定为可迭代的(因为 this Web IDL rule ¹)。如果您遇到具有 ES2015+ 功能但不会出于某种原因使集合可迭代的浏览器,您也可以对其进行 polyfill:
if (typeof Symbol !== "undefined" && Symbol.iterator && typeof NodeList !== "undefined" && NodeList.prototype && !NodeList.prototype[Symbol.iterator]) {
Object.defineProperty(NodeList.prototype, Symbol.iterator, {
value: Array.prototype[Symbol.iterator],
writable: true,
configurable: true
});
}
(对于 HTMLCollection 也是如此。)
这是一个使用两者的实例,在(例如)IE11 上试试这个(虽然它只会演示 forEach),NodeList 没有这些功能原生:
// Using only ES5 features so this runs on IE11
function log() {
if (typeof console !== "undefined" && console.log) {
console.log.apply(console, arguments);
}
}
if (typeof NodeList !== "undefined" && NodeList.prototype) {
// forEach
if (!NodeList.prototype.forEach) {
// Yes, there's really no need for `Object.defineProperty` here
console.log("Added forEach");
NodeList.prototype.forEach = Array.prototype.forEach;
}
// Iterability - won't happen on IE11 because it doesn't have Symbol
if (typeof Symbol !== "undefined" && Symbol.iterator && !NodeList.prototype[Symbol.iterator]) {
console.log("Added Symbol.iterator");
Object.defineProperty(NodeList.prototype, Symbol.iterator, {
value: Array.prototype[Symbol.iterator],
writable: true,
configurable: true
});
}
}
log("Testing forEach");
document.querySelectorAll(".container div").forEach(function(div) {
var html = div.innerHTML;
div.innerHTML = html[0].toUpperCase() + html.substring(1).toLowerCase();
});
// Iterable
if (typeof Symbol !== "undefined" && Symbol.iterator) {
// Using eval here to avoid causing syntax errors on IE11
log("Testing iterability");
eval(
'for (const div of document.querySelectorAll(".container div")) { ' +
' div.style.color = "blue"; ' +
'}'
);
}<div class="container">
<div>one</div>
<div>two</div>
<div>three</div>
<div>four</div>
</div>
¹ 这很令人困惑,因为 HTMLCollection 是可迭代的,但它没有标有 iterable declaration ,在 JavaScript DOM 绑定(bind)中奇怪的是 doesn't 意味着某些东西是可迭代的,这意味着它有 forEach, entries, keys, values, and 它是可迭代的。但是没有用 iterable 声明标记的 HTMLCollection 仍然是可迭代的。相反,它是可迭代的,因为 this Web IDL rule如前所述。
关于javascript - querySelectorAll 上的 forEach 在最近的 Microsoft 浏览器中不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46929157/
如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象
我想设置一个默认日期,例如实际日期,我该如何设置?还有如何在组合框中设置默认值顺便问一下,date_field_tag和date_field之间有什么区别? 最佳答案 试试这个:将默认日期作为第二个参数传递。youcorrectlysetthedefaultvalueofcomboboxasshowninyourquestion. 关于ruby-on-rails-date_field_tag,如何设置默认日期?[rails上的ruby],我们在StackOverflow上找到一个类似的问
在Rails4.0.2中,我使用s3_direct_upload和aws-sdkgems直接为s3存储桶上传文件。在开发环境中它工作正常,但在生产环境中它会抛出如下错误,ActionView::Template::Error(noimplicitconversionofnilintoString)在View中,create_cv_url,:id=>"s3_uploader",:key=>"cv_uploads/{unique_id}/${filename}",:key_starts_with=>"cv_uploads/",:callback_param=>"cv[direct_uplo
我将我的Rails应用程序部署到OpenShift,它运行良好,但我无法在生产服务器上运行“Rails控制台”。它给了我这个错误。我该如何解决这个问题?我尝试更新rubygems,但它也给出了权限被拒绝的错误,我也无法做到。railsc错误:Warning:You'reusingRubygems1.8.24withSpring.UpgradetoatleastRubygems2.1.0andrun`gempristine--all`forbetterstartupperformance./opt/rh/ruby193/root/usr/share/rubygems/rubygems
我正在尝试从Postgresql表(table1)中获取数据,该表由另一个相关表(property)的字段(table2)过滤。在纯SQL中,我会这样编写查询:SELECT*FROMtable1JOINtable2USING(table2_id)WHEREtable2.propertyLIKE'query%'这工作正常:scope:my_scope,->(query){includes(:table2).where("table2.property":query)}但我真正需要的是使用LIKE运算符进行过滤,而不是严格相等。然而,这是行不通的:scope:my_scope,->(que
我有一个.pfx格式的证书,我需要使用ruby提取公共(public)、私有(private)和CA证书。使用shell我可以这样做:#ExtractPublicKey(askforpassword)opensslpkcs12-infile.pfx-outfile_public.pem-clcerts-nokeys#ExtractCertificateAuthorityKey(askforpassword)opensslpkcs12-infile.pfx-outfile_ca.pem-cacerts-nokeys#ExtractPrivateKey(askforpassword)o
我目前正在尝试学习RubyonRails和测试框架RSpec。assigns在此RSpec测试中做什么?describe"GETindex"doit"assignsallmymodelas@mymodel"domymodel=Factory(:mymodel)get:indexassigns(:mymodels).shouldeq([mymodel])endend 最佳答案 assigns只是检查您在Controller中设置的实例变量的值。这里检查@mymodels。 关于ruby-o
我遇到了一个非常奇怪的问题,我很难解决。在我看来,我有一个与data-remote="true"和data-method="delete"的链接。当我单击该链接时,我可以看到对我的Rails服务器的DELETE请求。返回的JS代码会更改此链接的属性,其中包括href和data-method。再次单击此链接后,我的服务器收到了对新href的请求,但使用的是旧的data-method,即使我已将其从DELETE到POST(它仍然发送一个DELETE请求)。但是,如果我刷新页面,HTML与"new"HTML相同(随返回的JS发生变化),但它实际上发送了正确的请求类型。这就是这个问题令我困惑的
我了解instance_eval和class_eval之间的基本区别。我在玩弄时发现的是一些涉及attr_accessor的奇怪东西。这是一个例子:A=Class.newA.class_eval{attr_accessor:x}a=A.newa.x="x"a.x=>"x"#...expectedA.instance_eval{attr_accessor:y}A.y="y"=>NoMethodError:undefinedmethod`y='forA:Classa.y="y"=>"y"#WHATTT?这是怎么回事:instance_eval没有访问我们的A类(对象)然后它实际上将它添加到
我有一个集合选择:此方法的单选按钮是什么?谢谢 最佳答案 Rails3中没有这样的助手。在Rails4中,它是collection_radio_buttons. 关于ruby-on-rails-rails上的ruby:radiobuttonsforcollectionselect,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/18525986/