Javascript 在javascript中,如何在变量值改变时触发事件?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10638769/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 02:16:40  来源:igfitidea点击:

In javascript, how to trigger event when a variable's value is changed?

javascript

提问by Byron Sommardahl

I have two variables:

我有两个变量:

var trafficLightIsGreen = false; 
var someoneIsRunningTheLight = false;

I would like to trigger an event when the two variables agree with my conditions:

当两个变量符合我的条件时,我想触发一个事件:

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

Assuming that those two booleans can change in any moment, how can I trigger my go()method when they change according to the my conditions?

假设这两个布尔值可以随时更改,go()当它们根据我的条件更改时如何触发我的方法?

回答by JaredPar

There is no event which is raised when a given value is changed in Javascript. What you can do is provide a set of functions that wrap the specific values and generate events when they are called to modify the values.

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

Now you could call this function and link the callback to execute go():

现在你可以调用这个函数并将回调链接到执行go()

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

traffic.setIsGreen(true);

回答by Avatar

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

回答by Tadeck

The most reliable way is to use setters like that:

最可靠的方法是使用这样的 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(); 
    };
};

and then instead of assigning a value to a variable, you just invoke the setter:

然后不是为变量赋值,而是调用 setter:

setTrafficLightIsGreen(true);

回答by Steven10172

You could always have the variables be part of an object and then use a special function to modify the contents of it. or access them via window.

您可以始终将变量作为对象的一部分,然后使用特殊函数来修改它的内容。或通过window.

The following code can be used to fire custom events when values have been changed as long as you use the format changeIndex(myVars, 'variable', 5);as compared to variable = 5;

以下代码可用于在更改值时触发自定义事件,只要您使用changeIndex(myVars, 'variable', 5);variable = 5;

Example:

例子:

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

If you always wanted to pull from the windowobject you can modify changeIndexto always set obj to be window.

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

回答by Awesomeness01

If you were willing to have about a 1 millisecond delay between checks, you could place

如果您愿意在检查之间有大约 1 毫秒的延迟,您可以将

window.setInterval()

on it, for example this won't crash your browser:

在它上面,例如这不会使您的浏览器崩溃:

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

回答by Juan Mendes

There is no way to do it without polling with setInterval/Timeout.

如果不使用setInterval/Timeout.

If you can support Firefox only, you can use https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/watch

如果您只能支持 Firefox,则可以使用https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/watch

Which will tell you when a property of an object changes.

这将告诉您对象的属性何时发生变化。

Your best solution is probably making them part of an object and adding getters, setters that you can send out notifications yourself, as JaredPar showed in his answer

正如 JaredPar 在他的回答中所示,您最好的解决方案可能是将它们作为对象的一部分,并添加您可以自己发送通知的 getter、setter

回答by MyStream

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