2010-05-06 3 views
0

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

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

// 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); 
}); 

ответ

5

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

Пользовательские события могут иметь различные свойства. Одним из полезных свойств для этого случая является 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); 
     } 
    } 
}; 

При первом запуске события resourceLoaded также задано булево свойство для объекта 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, такие как окно для выполнения задания, если событие не имеет ничего общего с DOM.

+1

+1, хороший ответ –

+0

спасибо @Dimitar – Anurag

Смежные вопросы