我经历了所有的环状火灾只有一次'问题,但无法找到问题的解决方案。
我正在开发一个需要大量循环函数的项目,其中元素作为主题。我以为我会创建一个库函数(我认为'引用函数'是一个更好的术语),我可以稍后调用,每次只需要一行代码。所以我尝试过,但它的表现并不像我预期的那样,因为它只会触发一次。这是我的实验代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<span class="demo">See me.</span>
<span class="demo">See me.</span>
<span class="demo">See me.</span>
<span class="demo">See me.</span>
<script>
var forAll = function(elems) {
for (var i=0, n=elems.length; i<n; i++) {
console.log('The elems[i] == ' + elems[i]);
return elems[i];
}
}
var demos = document.querySelectorAll('.demo');
forAll(demos).style.color = 'red';
console.log('The forAll(demos) ==' + forAll(demos));
</script>
</body>
</html>
&#13;
从结果和控制台可以看到引发函数只触发一次。我究竟做错了什么?我完全自学了Javascript,所以如果我缺少基本的东西,请放轻松。
添加:在这种情况下,IE11是一个使用频繁的浏览器,因此forEach
不是一个选项。
答案 0 :(得分:3)
此函数中的for循环将只迭代一次:
var forAll = function(elems) {
for (var i=0, n=elems.length; i<n; i++) {
console.log('The elems[i] == ' + elems[i]);
return elems[i];
}
}
返回停止for循环并返回函数的执行。
修改:这是一个代码片段,可能会按照@AndroidNoobie
的建议执行您所期望的操作
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<span class="demo">See me.</span>
<span class="demo">See me.</span>
<span class="demo">See me.</span>
<span class="demo">See me.</span>
<script>
var forAll = function(elems) {
for (var i=0, n=elems.length; i<n; i++) {
elems[i].style.color = 'red';
}
return elems;
}
var demos = document.querySelectorAll('.demo');
console.log('The forAll(demos) ==' + forAll(demos));
</script>
</body>
</html>
答案 1 :(得分:2)
我认为您的实际问题是“如何在不支持forEach
的浏览器中实施forEach
- 类似行为?”
在这种情况下,你可以这样做:
if (!Array.prototype.forEach) {
Array.prototype.forEach = function(fn, scope) {
for(var i = 0, len = this.length; i < len; ++i) {
fn.call(scope, this[i], i, this);
}
}
}
然后你可以在你的数组上调用forEach
(尽管一般来说,修改像数组这样的内置对象的原型并不是一个好主意。)
但是你问的问题(为什么循环只迭代一次)已经被@facundo和@Pointy回答了。
修改:添加了代码段。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<span class="demo">See me.</span>
<span class="demo">See me.</span>
<span class="demo">See me.</span>
<span class="demo">See me.</span>
<script>
if (!Array.prototype.forEach) {
Array.prototype.forEach = function(fn, scope) {
for(var i = 0, len = this.length; i < len; ++i) {
fn.call(scope, this[i], i, this);
}
}
}
var demos = document.querySelectorAll('.demo');
demos.forEach(function(item){
item.style.color = 'red';
})
console.log('The forAll(demos) ==' + demos);
</script>
</body>
</html>
答案 2 :(得分:0)
最终,使用NodeLists使Internet Explorer(IE)支持forEach
变得非常容易。通过http://tips.tutorialhorizon.com/2017/01/06/object-doesnt-support-property-or-method-foreach/上的微小填充物:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<span class="demo">See me.</span>
<span class="demo">See me.</span>
<span class="demo">See me.</span>
<span class="demo">See me.</span>
<script>
// Polyfill to make IE9+ support forEach w/ NodeLists:
(function () {
if (typeof NodeList.prototype.forEach === "function")
return false;
else
NodeList.prototype.forEach = Array.prototype.forEach;
})();
// Works with NodeLists (i.e. HTMLcollections):
var demos = document.querySelectorAll('.demo');
demos.forEach(function(item) {
item.style.color = 'red';
})
// As well as with Arrays:
var gurkins = ['gur1', 'gur2', 'gur3'];
gurkins.forEach(function(item) {
console.log(item);
});
</script>
</body>
</html>
在IE11中测试,并且根据其模拟功能,它也可以在10和9中工作(不是8)。
感谢您的时间和精力,facundo和AndroidNoobie,但您可能会明白这是最好的解决方案。