Mootools - один объект Fx.Morph для разных эффектов? ... Также Morph onComplete - PullRequest
0 голосов
/ 30 марта 2011

У меня проблемы с объектом Mootools Fx.Morph.Я ожидал, что смогу использовать один объект несколько раз для создания разных эффектов.Я хотел бы переключить эффект на один div.Но мой эффект срабатывает только с первого раза.Есть ли мастера Fx.Morph, которые могли бы посоветовать?

Это мой класс

    var F = new Class({

    Implements: [Options, Events],

    myFX: null,

    dDiv: null,

    options: {
        container: null,
        width: '250px',
        background: '#ccc'
    },

    initialize: function(options) {
        this.setOptions(options);
        this.addDemoDiv();
    },

    addDemoDiv: function() {
        var dDiv = new Element('div', {
            'class': 'myClass',
            html: 'Click me!',
            styles: {
                padding: '20px',
                border: '1px solid #999',
                width: this.options.width,
                background: this.options.background
            },
            events: {
                click:  this.animate.bind(this)
            }
        });

        if (!this.container) {
            this.dDiv = dDiv.inject(document.body);
        } else {
            this.dDiv = dDiv.inject(this.container);
        }

        this.myFx = new Fx.Morph(dDiv);
    },

    animate: function(e) {
        this.dDiv.set('html', 'Hello world');
        this.myFx.start({
            height: 200,
            width: 500,
            link: 'cancel',
            onComplete: function(){
                this.dDiv.removeEvent('click', this.animate);
                this.dDiv.addEvent('click', this.deanimate.bind(this));
            }.bind(this)
        });
    },

    deanimate: function(e) {
        this.dDiv.set('html', 'Click me!');
        this.myFx.start({
            height: 20,
            width: 250,
            link: 'cancel',
            onComplete: function() {
                this.dDiv.removeEvent('click', this.deanimate);
                this.dDiv.addEvent('click', this.animate.bind(this));       
            }.bind(this)
        });
    }

});

window.addEvent('domready', function() {

    var item = new F({cntainer: 'container', background: '#ddd', width: '250px'});

});

Я пробовал довольно много вещей, включая отказ от свойства Fx.Morph.и просто вызывать .morph на div с каждым кликом.Похоже, это вызвало ужасные проблемы с браузером, возможно, потому, что он создавал новый объект Morph с каждым щелчком мыши и утечкой памяти.

Определенно вызывается метод deanimate (), потому что this.dDiv.set('html', 'Click me!'); работает.Но див не отступит.Я пытался применить другие эффекты, такие как цвет фона, но они тоже игнорируются.

Означает ли это, что объект Fx.Morph уничтожается после запуска start ()?

OnCompleteОбработчик Fx.Morph также не ведет себя так, как вы ожидаете.Когда я помещаю console.log в onComplete метода animate (), сообщение журнала отображается задолго до завершения анимации.Значит, onComplete только тогда, когда синтаксический анализ сценария завершен?

Или это просто я, чурбан?Любые указатели с благодарностью получены!

=============================

Добавлено позже

У меня естьудалось обойти эту проблему, потеряв объект Fx.Morph и анимировав его с помощью .morph и переменной-переключателя, например:

    animate: function(e) {
        if (!this.anim) {
            this.dDiv.set('html', 'Hello world');
            this.dDiv.morph({
                background: '#666',
                width: 500,
                height: 250
            });
            this.anim = true;
        } else {
            this.dDiv.set('html', 'Click me!');
            this.dDiv.morph({
                background: '#eee',
                width: 250,
                height: 100
            });
            this.anim = false;
        }
    }

Но если кто-нибудь может пролить свет на то, почему первая версия не былаработаю, буду очень признателен!

1 Ответ

1 голос
/ 30 марта 2011

это ошибка в привязке и удалении события.

this.animate.bind(this) возвращает функцию, которая НЕ совпадает с this.animate, с которой вы сравниваете при удалении события.

если вы связываете обратные вызовы событий, которые вам нужно удалить, вы должны сохранить их: http://jsfiddle.net/yLhHG/ (не полностью, но сначала сокращается. Подробнее:

в основном:

this.boundEvents = {
    click: this.animate.bind(this)
};

...

this.dDiv.removeEvent('click', this.boundEvents.click);

или

this.dDiv.addEvent('click', this.boundEvent = this.animate.bind(this));

...

this.dDiv.removeEvent("click", this.boundEvent);

и наконец:

Вы можете полностью переписать это, чтобы иметь один метод, но передать другой объект. обновит его через мгновение.

там: http://jsfiddle.net/yLhHG/1/

var F = new Class({

    Implements: [Options, Events],

    myFX: null,

    dDiv: null,

    options: {
        container: null,
        width: '250px',
        background: '#ccc',
        fx: {
            animate: {
                props: {
                    height: 200,
                    width: 500
                },
                html: "hello world"
            },
            deanimate: {
                props: {
                    height: 20,
                    width: 250
                },
                html: "bye world"
            }
        }
    },

    initialize: function(options) {
        this.setOptions(options);
        this.container = this.options.container || document.body;
        this.addDemoDiv();
    },

    addDemoDiv: function() {
        this.element =  new Element('div', {
            'class': 'myClass',
            html: 'Click me!',
            styles: {
                padding: '20px',
                border: '1px solid #999',
                width: this.options.width,
                background: this.options.background
            },
            events: {
                click: this.animate.bind(this)
            },
            morph: {
                link: "cancel",
                onComplete: function() {

                }.bind(this),
                onStart: function() {
                    this.element.set("html", this.options.fx[this.action].html);
                }.bind(this),
                onCancel: function() {
                   //
                }
            }
        }).inject(this.container);

    },

    animate: function(e) {
        this.action = this.action == "animate" ? "deanimate" : "animate";
        this.element.morph(this.options.fx[this.action].props);
    }
});

new F({
    cntainer: 'container',
    background: '#ddd',
    width: '250px'
});
...