В javascript, как инициировать событие при изменении значения переменной?
У меня есть две переменные:
var trafficLightIsGreen = false;
var someoneIsRunningTheLight = false;
Я хотел бы вызвать событие, когда две переменные согласуются с моими условиями:
if(trafficLightIsGreen && !someoneIsRunningTheLight){
go();
}
Предполагая, что эти два булева могут меняться в любой момент, как я могу вызвать метод go()
, когда они меняются в соответствии с моими условиями?
Ответы
Ответ 1
Нет события, которое возникает, когда заданное значение изменяется в 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); }
};
}
Теперь вы можете вызвать эту функцию и связать обратный вызов для выполнения go():
var traffic = Create(function(isGreen, isRunning) {
if (isGreen && !isRunning) {
go();
}
});
traffic.setIsGreen(true);
Ответ 2
Самый надежный способ - использовать такие сеттеры:
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();
};
};
а затем вместо присвоения значения переменной вы просто вызываете установщик:
setTrafficLightIsGreen(true);
Ответ 3
//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);
Ответ 4
Нет способа сделать это без опроса с помощью setInterval/Timeout
.
Если вы можете поддерживать только Firefox, вы можете использовать https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/watch
Что скажет вам, когда изменится свойство объекта.
Ваше лучшее решение, вероятно, делает их частью объекта и добавляет геттеры, сеттеры, которые вы можете сами отправлять уведомления, как показал JaredPar в своем ответе
Ответ 5
function should_i_go_now() {
if(trafficLightIsGreen && !someoneIsRunningTheLight) {
go();
} else {
setTimeout(function(){
should_i_go_now();
},30);
}
}
setTimeout(function(){
should_i_go_now();
},30);
Ответ 6
Вы всегда можете иметь переменные как часть объекта, а затем использовать специальную функцию для изменения ее содержимого. или получить доступ к ним через 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 в качестве окна.
Ответ 7
Если вы хотели иметь задержку в 1 миллисекунду между проверками, вы можете разместить
window.setInterval()
например, это не приведет к сбою вашего браузера:
window.setInterval(function() {
if (trafficLightIsGreen && !someoneIsRunningTheLight) {
go();
}
}, 1);