2012-05-17 201 views
18

我有两个变量:在JavaScript中,如何在变量值更改时触发事件?

var trafficLightIsGreen = false; 
var someoneIsRunningTheLight = false; 

我想触发一个事件时,这两个变量与我的条件达成一致:

if(trafficLightIsGreen && !someoneIsRunningTheLight){ 
    go(); 
} 

假设这两个布尔值可以在任何时刻改变,怎么能当我根据自己的情况改变时,我会触发我的go()方法吗?

+1

你已经尝试了什么? –

+0

用getter和setter方法将它们包装在对象中,然后在setter中触发事件。 –

+1

我想你可能想看看这个http://www.codeproject.com/Articles/13914/Observer-Design-Pattern-Using-JavaScript – MilkyWayJoe

回答

27

没有当给定值是引发事件在Javascript中更改。你可以做的是提供一组函数,它们包装特定的值并在调用它们来修改值时生成事件。

function Create(callback) { 
    var isGreen = false; 
    var isRunning = false; 
    return { 
    getIsGreen : function() { return isGreen; }, 
    setIsGreen : function(p) { isGreen = p; callback(isGreen, isRunning); }, 
    getIsRunning : function() { return isRunning; }, 
    setIsRunning : function(p) { isRunning = p; callback(isGreen, isRunning); } 
    }; 
} 

现在你可以调用这个函数和链接回调执行去()

var traffic = Create(function(isGreen, isRunning) { 
    if (isGreen && !isRunning) { 
    go(); 
    } 
}); 

traffic.setIsGreen(true); 
+0

+1我只是刚刚开始输入:)伟大的答案! –

0
function should_i_go_now() { 
    if(trafficLightIsGreen && !someoneIsRunningTheLight) { 
     go(); 
    } else { 
     setTimeout(function(){ 
      should_i_go_now(); 
     },30); 
    } 
} 
setTimeout(function(){ 
    should_i_go_now(); 
},30); 
1

最可靠的方法是使用setter方法类似:

var trafficLightIsGreen = false; 
var someoneIsRunningTheLight = false; 

var setTrafficLightIsGreen = function(val){ 
    trafficLightIsGreen = val; 
    if (trafficLightIsGreen and !someoneIsRunningTheLight){ 
     go(); 
    }; 
}; 
var setSomeoneIsRunningTheLight = function(val){ 
    trafficLightIsGreen = val; 
    if (trafficLightIsGreen and !someoneIsRunningTheLight){ 
     go(); 
    }; 
}; 

然后代替给一个变量赋值,你只需调用setter:

setTrafficLightIsGreen(true); 
0

您可以始终将变量作为对象的一部分,然后使用特殊功能修改其内容。或通过window访问它们。

下面的代码可以用来触发自定义事件时值已经只要你使用的格式changeIndex(myVars, 'variable', 5);相比variable = 5;改变

例子:

function changeIndex(obj, prop, value, orgProp) { 
    if(typeof prop == 'string') { // Check to see if the prop is a string (first run) 
     return changeIndex(obj, prop.split('.'), value, prop); 
    } else if (prop.length === 1 && value !== undefined && 
       typeof obj[prop[0]] === typeof value) { 
     // Check to see if the value of the passed argument matches the type of the current value 
     // Send custom event that the value has changed 
     var event = new CustomEvent('valueChanged', {'detail': { 
                  prop : orgProp, 
                  oldValue : obj[prop[0]], 
                  newValue : value 
                 } 
                }); 
     window.dispatchEvent(event); // Send the custom event to the window 
     return obj[prop[0]] = value; // Set the value 
    } else if(value === undefined || typeof obj[prop[0]] !== typeof value) { 
     return; 
    } else { 
     // Recurse through the prop to get the correct property to change 
     return changeIndex(obj[prop[0]], prop.slice(1), value); 
    } 
}; 
window.addEventListener('valueChanged', function(e) { 
    console.log("The value has changed for: " + e.detail.prop); 
}); 
var myVars = {}; 
myVars.trafficLightIsGreen = false; 
myVars.someoneIsRunningTheLight = false; 
myVars.driverName = "John"; 

changeIndex(myVars, 'driverName', "Paul"); // The value has changed for: driverName 
changeIndex(myVars, 'trafficLightIsGreen', true); // The value has changed for: traggicIsGreen 
changeIndex(myVars, 'trafficLightIsGreen', 'false'); // Error. Doesn't set any value 

var carname = "Pontiac"; 
var carNumber = 4; 
changeIndex(window, 'carname', "Honda"); // The value has changed for: carname 
changeIndex(window, 'carNumber', 4); // The value has changed for: carNumber 

如果你一直想拉从window对象中,您可以修改changeIndex以始终将obj设置为窗口。

0

如果你愿意有关于检查之间的1毫秒的延迟,你可以放置

window.setInterval() 

就可以了,比如这不会崩溃您的浏览器:

window.setInterval(function() { 
    if (trafficLightIsGreen && !someoneIsRunningTheLight) { 
     go(); 
    } 
}, 1); 
+1

这是不错的编码练习,用'setInterval'代替getter和setter? – lowtechsun

1
//ex: 
/* 
var x1 = {currentStatus:undefined}; 
your need is x1.currentStatus value is change trigger event ? 
below the code is use try it. 
*/ 
function statusChange(){ 
    console.log("x1.currentStatus_value_is_changed"+x1.eventCurrentStatus); 
}; 

var x1 = { 
    eventCurrentStatus:undefined, 
    get currentStatus(){ 
     return this.eventCurrentStatus; 
    }, 
    set currentStatus(val){ 
     this.eventCurrentStatus=val; 
    } 
}; 
console.log("eventCurrentStatus = "+ x1.eventCurrentStatus); 
x1.currentStatus="create" 
console.log("eventCurrentStatus = "+ x1.eventCurrentStatus); 
x1.currentStatus="edit" 
console.log("eventCurrentStatus = "+ x1.eventCurrentStatus); 
console.log("currentStatus = "+ x1.currentStatus); 
相关问题