2010-05-06 49 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 
    }); 
}); 

如果可能的话,我想resourcesAreLoadeddomready的功能,并执行代码立即如果事件已经发射:

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,它基本上是一个函数,当您通过调用<element>.addEvent(<name>, <fn>)将该事件添加到某个DOM元素时会调用该函数。你的函数onAdd将被调用,并通过fn作为参数。检查事件是否已经被触发,如果是,立即拨打fn,否则什么也不做。详细了解底部Hash: Element.Events部分下自定义事件的属性。

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

当您第一次触发resourcesLoaded事件时,还为窗口对象设置了布尔属性。 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,很好回答 – 2010-05-07 09:59:45

+0

thanks @Dimitar – Anurag 2010-05-07 16:11:48