2

编辑:原标题为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);
}

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

4

1 回答 1

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 的引用等 - 缓存。

于 2013-06-27T12:44:41.470 回答