【问题标题】:loop through a javascript object循环一个 javascript 对象
【发布时间】:2012-07-20 14:51:52
【问题描述】:

我有一个看起来像这样的 javascript 对象,

var telephones = {
        /*
        "phone" : {
            duration    :   time it takes to animate element in,
            leftIn      :   position of element once on the incoming animation
            leftOut     :   position of element on the outgoing animation
            delay       :   delay between two animations
        }
        */
        "phone1": {
            duration    :   850,
            leftIn      :   "408px",
            leftOut     :   "9999px",
            delay       :   0,
        },
        "phone2" : {
            duration    :   600,
            leftIn      :   "962px",
            leftOut     :   "999px",
            delay       :   setDelay(),
        },
        "phone3" : {
            duration    :   657,
            leftIn      :   "753px",
            leftOut     :   "9999px",
            delay       :   0,
        },
        "phone4" : {
            duration    :   900,
            leftIn      :   "1000px",
            leftOut     :   "9999px",
            delay       :   setDelay(),
        },
        "phone5" : {
            duration    :   1200,
            leftIn      :   "800px",
            leftOut     :   "9999px",
            delay       :   0,
        },
        "phone6" : {
            duration    :   792,
            leftIn      :   "900px",
            leftOut     :   "9999px",
            delay       :   setDelay(),
        },

    };

我正在使用上述对象来尝试为幻灯片中的单个元素设置动画,该幻灯片已经通过 jquery 循环插件进行了动画处理。我正在通过以下方式使用代码,

$('#slideshow').cycle({
    fx: 'scrollHorz',
    before  :   triggerParralex,
    after   :   removeParralex,
    easing  :   'easeOutCubic',
    speed   :   2000
});

所以上面的代码启动了循环插件。然后我使用 before 和 after 回调来运行另外 2 个函数,这些函数看起来像这样,

function bgChange(curr, next, opts) {
    var background = $(".current").attr('data-background');
    $.backstretch(background, {target: "#backstrectch", centeredY: true, speed: 800});
}

function triggerParralex(curr, next, opts) {
    //move any phones that are in the viewport
    for (var key in telephones) {
        var obj = telephones[key];
        for (var prop in obj) {
            if($(".current ." + key).length) { //does .custom .phone1/2/3/4/5/6 exist if it does we can carry on
                setTimeout(function() {
                    $(".current ." + key).animate({
                        "left"      :   obj["leftOut"],
                        "opacity"   :   0
                    }, obj["duration"]);
                }, obj["delay"]);
            }
        }
    }

    //change the background
    bgChange();

    //remove the current class from the DIV
    $(this).parent().find('section.current').removeClass('current');

}

function removeParralex(curr, next, opts) {

    //give the slide a current class so that we can identify it.
    $(this).addClass('current');

    //animate in any phones that belong to the current slide
    for (var key in telephones) {
        var obj = telephones[key];
        for (var prop in obj) {
            console.log(obj["leftIn"])
            if($(".current ." + key).length) { //does .custom .phone1/2/3/4/5/6 exist if it does we can carry on
                setTimeout(function() {
                    $(".current .phone1").animate({
                        "left"      :   obj["leftIn"],
                        "opacity"   :   1
                    }, obj["duration"]);
                }, obj["delay"]);
            }
        }
    }

}

我的问题如下,

我正在尝试为我的部分元素中的图像设置动画,部分元素已经通过循环插件滑动,这对我来说感觉就像它正在阻止我的图像在稍后阶段被动画化?

第二个问题似乎是,虽然我的脚本会很高兴地找到$(".current .phone1") 似乎只是从对象中添加了phone6 的属性,但我已经做了一个fiddle

正如您从小提琴中看到的那样,带有#slideshow 的部分正在循环,但是其中的图像没有动画...为什么?

【问题讨论】:

  • 您正在循环内创建一个函数。请参阅Javascript closure inside loops - simple practical example 了解此问题的解释和解决方案。
  • 谢谢,但你能指出我在哪里创建函数吗?
  • setTimeout(function() {....})... 执行回调时,obj 将具有循环最后一次迭代的值。另外,我认为您不想遍历似乎没有意义的“动画对象”的每个属性。
  • 谢谢,我已经阅读了您留给我的链接,但我真的不明白如何修复我的代码...任何线索?

标签: javascript jquery object jquery-animate


【解决方案1】:

正如 Felix Kling 在评论中所说,您有一个经典的“闭环内循环”问题。

这是一个(经典的)解决方案:

for (var key in telephones) {
    if($(".current ." + key).length) { //does .custom .phone1/2/3/4/5/6 exist if it does we can carry on
        var obj = telephones[key];
        (function(obj){
            setTimeout(function() {
                $(".current .phone1").animate({
                    "left"      :   obj["leftIn"],
                    "opacity"   :   1
                }, obj["duration"]);
            }, obj["delay"]);
        })(obj);
    }
}

这个想法是将 obj 嵌入另一个闭包中,将其与循环隔离,从而防止其更改。

【讨论】:

  • 虽然自调用函数也是一个闭包,但该解决方案的重要方面是该函数会立即执行,因此此时会解析变量(并且不迟)。
  • 感谢此修复,我已尝试实施,但仍然遇到问题,是否可以编辑我的小提琴修复,以便我可以看到它的实际效果?
  • 我进行了一些清理编辑。循环中有奇怪的东西。
  • @dystroy 你在哪里编辑过?我的小提琴?是否有指向您的编辑的链接?
  • 我编辑了我的答案。但我只是说明了闭包问题,并查看了其余可能的 js 问题,我不会尝试分析您使用我不想学习的插件的整个页面(至少循环和回溯)。
猜你喜欢
  • 1970-01-01
  • 2021-07-25
  • 2013-12-12
  • 2017-01-25
  • 1970-01-01
  • 2016-07-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多