Эмулировать событие domready с пользовательским событием (mootools) - PullRequest
0 голосов
/ 06 мая 2010

Мне нужно запустить одноразовое пользовательское событие, которое функционирует как событие domready, в том случае, если новые события добавляются после того, как событие произошло, они запускаются немедленно.

Это для некоторого кода, который не может быть выполнен, пока определенные данные и ресурсы не будут инициализированы, поэтому я хочу сделать что-то вроде этого:

// I am including a script (loadResources.js) to load data and other resources,
// when loadResources.js is done doing it's thing it will fire resourcesAreLoaded with:
window.fireEvent('resourcesAreLoaded');

window.addEvent('resourcesAreLoaded', function() {
    // this is fine 
});
$('mybutton').addEvent('click', function() {
    window.addEvent('resourcesAreLoaded', function() {
        // this is not fine, because resourcesAreLoaded has already fired
        // by the time the button is clicked
    });
});

Если возможно, я бы хотел, чтобы resourcesAreLoaded функционировал как domready, и немедленно выполнял код, если событие уже сработало:

window.addEvent('testIsReady', function() {
    alert('firing test');       
});
window.fireEvent('testIsReady');
window.addEvent('test', function() {
    // this will never execute unless I call fireEvent('testIsReady') again
    alert('test 2');        
});

window.addEvent('domready', function() {
    alert('domready is firing');        
});

window.addEvent('domready', function() {
    setTimeout(function() {
        alert('domready has already fired, so this is executed immediately');       
    }, 500);
});

1 Ответ

5 голосов
/ 07 мая 2010

Вам нужно будет сохранить состояние, если пользовательское событие было запущено где-то. Одно хорошее место - Магазин Элементов .

Для пользовательских событий могут быть определены различные свойства. Одним из полезных свойств для этого случая является onAdd, который в основном является функцией, которая вызывается, когда вы добавляете это событие к некоторому элементу DOM, вызывая <element>.addEvent(<name>, <fn>). Ваша функция для onAdd будет вызвана и передана fn в качестве параметра. Проверьте, было ли событие уже запущено, и если это так, немедленно вызовите fn, иначе ничего не делайте. Подробнее о свойствах пользовательских событий читайте в разделе Hash: Element.Events в нижней части.

Element.Events.resourcesLoaded = {
    onAdd: function(fn) {
        if(window.retrieve('resourcesLoaded')) {
            fn.call(this);
        }
    }
};

Когда вы впервые запускаете событие resourcesLoaded, также задайте логическое свойство для объекта window. onAdd теперь может получить это значение, чтобы узнать, нужно ли немедленно запускать обработчики событий.

window.fireEvent('resourcesLoaded');
window.store('resourcesLoaded', true);

Это должно сделать это. Вот два тестовых сценария:

  1. Ресурсы не были загружены , поэтому обратный вызов не должен запускаться немедленно.

    window.addEvent('resourcesLoaded', function() { alert("should wait"); });

  2. Ресурсы загружены , поэтому обратный вызов срабатывает немедленно.

    window.addEvent('resourcesLoaded', function() { alert("shouldn't wait"); });

Я взял это из исходного кода MooTools. Вот как он обрабатывает событие domready.

В дополнение к этому, одинаково легко реализовать события внутри ваших собственных пользовательских объектов, и вам не нужно полагаться на элементы DOM, такие как window, для выполнения работы, если событие не имеет ничего общего с DOM. *

...