如何创建一个检测布尔变量是否为真的事件监听器?

例如,我有var menu_ready = false; 。 我有一个ajax函数,当ajax完成时将menu_ready设置为true:

 //set up event listener here $(...).load(..., function() { ... menu_ready = true; } 

如何设置等待menu_ready为真的事件监听器?

一种方法是持续轮询:

 function checkMenu() { if (!menu_ready) { setTimeout("checkMenu();", 1000); return; } else { // menu_ready is true, so do what you need to do here. } } 

和…

  

您不能将事件侦听器附加到JavaScript变量本身,但您可以伪造它。 而不是boolean var,使用带有getsetlisten方法的对象:

 function Bool(initialValue) { var bool = !!initialValue; var listeners = []; var returnVal = function(value) { if (arguments.length) { var oldValue = bool; bool = !!value; listeners.forEach(function (listener, i, list) { listener.call(returnVal, { oldValue: oldValue, newValue: bool }); }); } return bool }; returnVal.addListener = function(fn) { if (typeof fn == "function") { listeners.push(fn); } else { throw "Not a function!"; } }; return returnVal; } 

你会像这样使用它:

 var menu_ready = Bool(false); if (menu_ready()) { // this code won't get executed, because menu_ready() will currently return false; } menu_ready.addListener(function (e) { if (e.oldValue != e.newValue) { // value changed! } }); menu_ready(true); // listeners are called. 

没有跨浏览器(跨平台)事件可以完成这项工作。 例如,有一些非常具体的机制来观察对象属性,但没有什么值得注意的是布尔值(imo)。

您希望在将该变量设置为true时执行回调函数。 你也可以应用一些jQuery糖:

 function myCallbackReference() { alert('yay'); } $('#foobar').load('/some/code', function() { menu_ready = true; }).done( myCallbackReference ); 

您无法将事件侦听器附加到单个变量。

执行此操作的最佳方法是将变量放在对象中,并使变量的所有用户通过“get”和“set”方法或更具体命名的方法访问它。 设置值时,您可以检查该值是否实际以您感兴趣的方式发生变化并采取相应措施。 这是一个例子:

 var _isMenuReady = false; // do not access this directly function isMenuReady() { return(_isMenuReady); } function setMenuReady(val) { if (arguments.length < 1) { val = true; } if (!_isMenuReady && (val)) { _isMenuReady = val; // _isMenuReady has gone from false to true // do whatever you need to do now } _isMenuReady = val; } // sample code var ready = isMenuReady(); // returns whether the menu is ready or not setMenuReady(); // sets the menu to be ready now setMenuReady(false); // sets it back to not ready 

它甚至可以使它成为对象的私有成员,因此没有人可以直接在实际的访问器方法之外访问它(尽管如果所有代码都是你的,并且你通过不直接访问变量进行合作,则不需要这样做)。 但是,如果您想使其真正私有,请参阅此文章以获取有关如何创建私有成员的信息。 从本质上讲,您创建了一个持久的函数闭包,其局部变量只能在函数内部访问。 这是一种很酷的技巧。

 function menuReadyTracker(initialValue) { var value = initialValue; var subscribers = []; this.get = function () { return(value); }; this.set = function(newVal) { if (newVal != value) { value = newVal; var o; for (var i = 0; i < subscribers.length; i++) { o = subscribers[i]; o.func.call(o.ctx, o.data); } } } // call subscribe to register a notification callback this.subscribe = function(f, data, ctx) { var o = {}; o.func = f; o.data = data; o.ctx = ctx || window; subscribers.push(o); } // call unsubscribe to remove a notification callback this.unsubscribe = function(f, data, ctx) { var o; var newSubscribers = []; for (var i = 0; i < subscribers.length; i++) { o = subscribers[i]; if (o.func != f || o.data != data || o.ctx != ctx) { newSubscribers.push(o); // copy if it doesn't match } } subscribers = newSubscribers; } } var menuReady = new menuReadyTracker(false); menuReady.subscribe(myNotification, "in real-time."); console.log(menuReady.get()); menuReady.set(true); console.log(menuReady.get()); // this function gets called whenever the menu flag goes from false to true // you can have as many subscribers to this notification as you want and // they code that handles the notifications can be anywhere you want in your // code base as the notification handlers are registered with the subscribe method function myNotification(data) { alert("I got notified " + data); } 

jsFiddle: http : //jsfiddle.net/jfriend00/PYJef/

 function menuReady(){ // Do whatever it is you need done when menu is ready } $(...).load(..., function() { menuReady();// menuReady is called on callback }); 

为什么不创建一个函数menuReady会在你想要的时候触发?

 menuReady(); 
 Utils = { eventRegister_globalVariable : function(variableName,handlers){ eventRegister_JsonVariable(this,variableName,handlers); }, eventRegister_jsonVariable : function(jsonObj,variableName,handlers){ if(jsonObj.eventRegisteredVariable === undefined) { jsonObj.eventRegisteredVariable={};//this Object is used for trigger event in javascript variable value changes ku } Object.defineProperty(jsonObj, variableName , { get: function() { return jsonObj.eventRegisteredVariable[variableName] }, set: function(value) { jsonObj.eventRegisteredVariable[variableName] = value; handlers(jsonObj.eventRegisteredVariable[variableName]);} }); }