堆叠补间

时间:2013-06-26 17:43:06

标签: javascript mootools

编辑:最初标题为 Mootools'儿童索引刷新

对于我来说,真的有点难以100%确定Mootools发动机罩下面真正发生的事情,但这就是它的工作方式:

当一个元素从DOM中分离然后重新插入到它的容器底部时,似乎下一个重复的getNext()getChildren()[0]或类似的元素不会返回人类认为的元素首先,当他查看HTML时。

以下是我想要做的代码。我很茫然,我甚至不确定我上面描述的是真正的问题。

function slideNext() {
    window.clearTimeout(sliderTimeout);
    var slider = $('slider');
    slider.set('tween', {duration: 500, onComplete: function(){
        var slide = slider.getFirst('.block').clone();
        slider.grab(slide, 'bottom');
        slider.getFirst('.block').destroy();
        slider.erase('style');
        sliderTimeout = window.setTimeout(function(){slideNext();}, 5000);
    }});
    slider.tween('margin-left', 0 - slider.getSize().x);
}

编辑:在onComplete函数中放置alert(slide.get('html'));会清除一些内容。每次运行该函数时,警报对话框的数量都会奇怪地增加,即使它只应警告一次。这似乎意味着通过使用slider.set('tween', {blabla})反复导致堆叠补间,这让我觉得孩子索引可能有问题,但显然情况并非如此。这种变化非常有效:

function slideNext() {
    window.clearTimeout(sliderTimeout);
    var slider = $('slider');
    var myFx = new Fx.Tween('slider', {
        duration: 500, 
        property: 'margin-left',
        onComplete: function(){
            var slide = slider.getFirst('.block').clone();
            slider.grab(slide, 'bottom');
            slider.getFirst('.block').destroy();
            slider.erase('style');
            sliderTimeout = window.setTimeout(function(){slideNext();}, 5000);
        }
    });
    myFx.start(0, 0 - slider.getSize().x);
}

有人可以解释为什么会这样吗?

1 个答案:

答案 0 :(得分:0)

基本上,在原文中:

slider.set('tween', {duration: 500, onComplete: function(){
    var slide = slider.getFirst('.block').clone();
    slider.grab(slide, 'bottom');
    slider.getFirst('.block').destroy();
    slider.erase('style'); 
    sliderTimeout = window.setTimeout(function(){slideNext();}, 5000);
}});

您正在调用wteen实例上的setter,该实例检测前缀为on-(Complete)的事件,将其解压缩并运行this.addEvent('complete', cb);。这并没有取代前一个,mootools有一个带有多个回调的事件api,而不是一个静态回调。

解决问题的一种方法是在调用下一个事件之前分离事件,但这很愚蠢,因为事件是相同的。更改一次设置补间实例更有意义。元素不会改变。请注意我真的不知道你用它做什么。似乎有点多余,但这里有:http://jsfiddle.net/dimitar/3qWX7/

(function(){
    // set the slider el cached, store the tween instance.
    var slider = document.id('slider').set('tween', {
        duration: 500,
        link: 'cancel',
        onComplete: function(){
            var block = this.element.getFirst('.block');
            // this.element === slider
            this.element.adopt(block.clone());
            block.destroy();
            this.element.erase('style'); // er? why... 
            // console.log(this.element);
            this.timer = slideNext.delay(5000, this);
        }
    });

    // you can get instance by doing:
    slider.get('tween'); // Fx.Tween instance

    function slideNext(){
        // this == Fx.Tween instance. 
        window.clearTimeout(this.timer);
        this.element.tween('margin-left', [0, this.element.getSize().x]);
    }

    slider.tween('margin-left', 40);
}());

这是其他补间的缺点 - 事件未与您补间的属性相关联。如果你这样做,你必须使用fx.morph并删除/添加事件。

tl; dr;:总是重用fx实例,引用dom等 - 缓存。