【问题标题】:setInterval only runs once when trying to run a function that loops through querySelectorAll arraysetInterval 仅在尝试运行循环通过 querySelectorAll 数组的函数时运行一次
【发布时间】:2016-08-02 00:45:07
【问题描述】:

我是javascript新手,所以可能缺乏基本的了解,但我不明白为什么这段代码会出现问题。

我正在尝试创建“控制台输入效果”,这基本上意味着所选文本应该看起来像是在页面加载后“实时”输入的。我知道那里有类似的效果,但我想在 vanilla JS(无框架)中做到这一点。

到目前为止我所做的事情(伪代码):

  1. 使用 .console-effect 类获取元素,最终将它们存储在“elementList”中
  2. 循环遍历元素并在它们拥有的文本末尾添加一个光标。
  3. (这里我失败了:()使光标闪烁

在调试时我发现在遍历游标(使它们闪烁)一次之后,方法“elem.style.opacity”说它拥有的元素是“未定义”...

document.body.onload = function() {

    function addCursor(element) {
        // Create a Span with the cursor character and give it an class of .cursor
        var newSpan = document.createElement('span'),
            newSpanText = document.createTextNode('|');
        newSpan.appendChild(newSpanText);
        newSpan.className = 'cursor';

        //Add newSpan to the element var(passed trough the function)
        element.appendChild(newSpan);
    }

    function animateCursor() {
        var cursors = document.querySelectorAll('.cursor');

        for (var i = 0; i < cursors.length; i++) {
            cursors[i].style.opacity = '0';
            setTimeout(function() {
                cursors[i].style.opacity = '1';
            }, 500 );
        }
    }

    setInterval('animateCursor()', 1000);

    var elementsList = document.querySelectorAll('.console-effect');
    for (var i = 0; i < elementsList.length ; i++) {
        addCursor(elementsList[i]);
    }

};

【问题讨论】:

标签: javascript animation for-loop setinterval


【解决方案1】:

您在 Timeout 中调用的函数不知道您的光标:

setTimeout(function() {
  cursors[i].style.opacity = '1';
}, 500 );

这样的事情应该可以工作:

setTimeout(function() {
  this.style.opacity = '1';
}.bind(cursors[i]), 500 );

即使我确信您会找到一些解释,如果您需要帮助,请告诉我。 顺便说一句:Lambda Ninja 将函数作为字符串传递是正确的——你应该改变它

【讨论】:

  • 好的,我明白了,如果我也执行“setTimeout(function(cursors[i]) {...”之类的操作,它应该工作吗?如果可以,哪个更好?
  • 这不起作用,参数将是未定义的。 “bind()”将在第一个参数的范围内执行函数,在内部存储所有其他参数并在执行时将它们作为参数传递。使用“this”将是对 scope = 1st 参数的内部引用。所以你可以做的是选择你想要的任何范围并将光标作为参数传递,例如function(cursor) { .. }.bind({}, cursons[i]) .. 这样它就绑定到一个空对象,“this”将是 {}(没有任何意义——只是一个例子)跨度>
【解决方案2】:

setInterval() 中的animateCursor() 中删除()

也就是说,像这样:

setInterval(animateCursor, 1000);

括号使函数立即运行;不带括号实际上将它作为参数变量传递给setInterval()

【讨论】:

  • “括号使函数立即运行”。 OP 将其包装成撇号,因此它是一个表达式。
  • 好的,谢谢,我有个问题,即使我在里面放了一个console.log,我用撇号把它包起来它仍然运行,它不应该认为它是一个字符串吗?跨度>
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多