简体   繁体   English

匿名函数中的JavaScript未定义变量

[英]JavaScript undefined variable in an anonymous function

This code is supposed to switch the display property of all children elements of #slide-container to "block" with time delay two seconds between the switches. 假定该代码将#slide-container的所有子元素的显示属性切换为“阻止”,并且两次切换之间的时间延迟为2秒。

var magic = window.setInterval(function(){
    if (document.readyState === "complete") {
            var children = document.getElementById('slide-container').children;
            for (var i = 0; children.length > i; i++ ) {
                setTimeout(function(){
                    children[i].style.display = "block";
                    console.log(i);
                },2000);
            }
            magic = window.clearInterval(magic);
        } else {
            console.log("...");
        }
}, 1000);

I am using it along with this html: 我将其与以下html一起使用:

<!DOCTYPE html>
<html>

    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
        <title></title>
        <meta name="description" content="">
        <meta name="viewport" content="width=device-width">
    </head>
    <body>
        <ul id="slide-container">
            <li style="display: none;"><img src="http://i.imgur.com/8qBcyzc.jpg"></li>
            <li style="display: none;"><img src="http://i.imgur.com/oxMTFTF.png"></li>
            <li style="display: none;"><img src="http://i.imgur.com/JTM6Yqg.jpg"></li>
        </ul>

    </body>
</html>

I get error Uncaught TypeError: Cannot read property 'style' of undefined 我收到错误Uncaught TypeError: Cannot read property 'style' of undefined

It says it cannot find children or children[0]. 它说找不到孩子或孩子[0]。 But that variable has been specified and the dom nodes exist. 但是已经指定了该变量,并且存在dom节点。

Try encasing the setTimeout in an IIFE (Immediately invoked function expression) 尝试将setTimeout封装在IIFE中(立即调用的函数表达式)

 for (var i = 0; children.length > i; i++) {
      (function (index) {
                setTimeout(function () {
                    children[index].style.display = "block";
                    console.log(i);
                }, 2000);
            })(i);
        }

Check Fiddle 检查小提琴

The reference of i is common to all the functions executed by setTimeout . i的引用是setTimeout执行的所有功能的共同点。 So by the time the function inside executes , the value of i will point to children.length . 因此,当内部函数执行时, i的值将指向children.length

But there is no element that refers to children[children.length] which does not exist and throws an error. 但是没有任何元素引用不存在的child children[children.length]并引发错误。

By the time setTimeout is ready i will be the length of children so you have to capture the value of i setTimeout准备好的时候, i将是children的长度,因此您必须捕获i的值

try this 尝试这个

var time = 2000;
for (var i = 0; children.length > i; i++ ) {
    (function( child, time) {
       window.setTimeout(function() {
          child.style.display = "block";
       }, time);
    }( children[i], time));
    time += 2000;
}

or you could do this. 或者你可以这样做。 ... I have fixed the delay thing ...我已经解决了延迟的问题

var hideElement = function( element, time) {
   window.setTimeout(function() {
      element.style.display = 'block';
   }, time);
};

var time = 2000;
for (var i = 0; children.length > i; i++ ) {
   hideElement(children[i], time);
   time += 2000;
}

Closure issue. 关闭问题。
Try adding a 3rd parameter to the setTimeout (doesn't work): 尝试向setTimeout中添加第三个参数(无效):

setTimeout(function(i){
   children[i].style.display = "block";
   console.log(i);
}, 2000, i);

Example

Another formate: 另一个护身符:

    var i = 0;
    var timer = setInterval(function () {
        children[i].style.display = "block";
        i++;
        if (i == children.length) {
            clearInterval(timer);
        }
    }, 2000);

EXAMPLE

ES6 is around the corner, the let statement is especially built for situations like this: ES6迫在眉睫, let语句专门针对以下情况构建:

for (let i = 0; children.length > i; i++ ) {
   setTimeout(function(){
      children[i].style.display = "block";
      console.log(i);
   }, 2000);
}

However this is not the answer you need for right now. 但是,这不是您现在需要的答案。 This was just a note. 这只是一个注释。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM