监听JavaScript中的变量更改

某个变量的值更改时,是否可能在JS中触发事件?接受JQuery。

番长猴子古一2020/03/13 18:24:48
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]);}
                    });
            }
JinJin猪猪2020/03/13 18:24:48

这个答案开始,我找到了最简单的方法

// variable holding your data
const state = {
  count: null,
  update() {
    console.log(`this gets called and your value is ${this.pageNumber}`);
  },
  get pageNumber() {
    return this.count;
  },
  set pageNumber(pageNumber) {
    this.count = pageNumber;
    // here you call the code you need
    this.update(this.count);
  }
};

接着:

state.pageNumber = 0;
// watch the console

state.pageNumber = 15;
// watch the console
乐猪猪2020/03/13 18:24:48

一个相当简单和简单的解决方案是仅使用函数调用来设置全局变量的值,而从不直接设置其值。这样,您可以完全控制:

var globalVar;

function setGlobalVar(value) {
    globalVar = value;
    console.log("Value of globalVar set to: " + globalVar);
    //Whatever else
}

没有办法强制执行此操作,它只需要编程grep规程...尽管您可以使用(或类似方法)检查​​代码中没有地方直接设置的值globalVar

或者,您也可以将其封装在一个对象以及用户getter和setter方法中……只是一个想法。

番长猴子古一2020/03/13 18:24:48
//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;
      //your function();
    }
};

要么

/*  var x1 = {
eventCurrentStatus:undefined,
currentStatus : {
    get : function(){
        return Events.eventCurrentStatus
        },
    set : function(status){
        Events.eventCurrentStatus=status;

    },
}*/
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);

要么

/* global variable ku*/
    var jsVarEvents={};
    Object.defineProperty(window, "globalvar1", {//no i18n
        get: function() { return window.jsVarEvents.globalvarTemp},
        set: function(value) { window.window.jsVarEvents.globalvarTemp = value; }
    });
    console.log(globalvar1);
    globalvar1=1;
    console.log(globalvar1);
路易猪猪2020/03/13 18:24:48

请大家记住最初的问题是变量,而不是对象;)

除了上述所有答案之外,我还创建了一个名为forTheWatch.js的小型库,该库使用相同的方式来捕获和回调javascript中常规全局变量的更改。

与JQUERY变量兼容,无需使用OBJECTS,如果需要,您可以直接传递多个变量的ARRAY。

如果有帮助...:https : //bitbucket.org/esabora/forthewatch
基本上,您只需要调用该函数:
watchIt("theVariableToWatch", "varChangedFunctionCallback");

如果不相关,请提前抱歉。

西里Jim番长2020/03/13 18:24:48

您正在寻找的功能可以通过使用“ defineProperty()”方法来实现,该方法仅适用于现代浏览器:

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty

如果您需要更多的跨浏览器支持,我已经编写了一个具有一些类似功能的jQuery扩展:

https://github.com/jarederaj/jQueue

一个小的jQuery扩展,用于处理对存在变量,对象或键的队列回调。您可以将任意数量的回调分配给可能受后台运行的进程影响的任意数量的数据点。jQueue侦听并等待您指定的这些数据存在,然后使用其参数触发正确的回调。

Pro西门2020/03/13 18:24:48

不是直接的:您需要一对具有某种“ addListener / removeListener”接口的吸气剂/吸气剂或NPAPI插件(但这完全是另一回事了)。

神无StafanTom2020/03/13 18:24:47

对于几年后的调优:

提供了适用于大多数浏览器(和IE6 +)的解决方案,该解决方案使用onpropertychange事件和更新的规范defineProperty。轻微的缺点是您需要使变量成为dom对象。

详细信息:

http://johndyer.name/native-browser-get-set-properties-in-javascript/

逆天L2020/03/13 18:24:47

如果您使用的是jQuery {UI}(每个人都应该使用:-)),则可以将.change()与隐藏的<input />元素一起使用。

MandyJinJin2020/03/13 18:24:47

没有。

但是,如果真的那么重要,则有两种选择(第一种经过测试,第二种未经测试):

首先,使用setter和getter,如下所示:

var myobj = {a : 1};

function create_gets_sets(obj) { // make this a framework/global function
    var proxy = {}
    for ( var i in obj ) {
        if (obj.hasOwnProperty(i)) {
            var k = i;
            proxy["set_"+i] = function (val) { this[k] = val; };
            proxy["get_"+i] = function ()    { return this[k]; };
        }
    }
    for (var i in proxy) {
        if (proxy.hasOwnProperty(i)) {
            obj[i] = proxy[i];
        }
    }
}

create_gets_sets(myobj);

那么您可以执行以下操作:

function listen_to(obj, prop, handler) {
    var current_setter = obj["set_" + prop];
    var old_val = obj["get_" + prop]();
    obj["set_" + prop] = function(val) { current_setter.apply(obj, [old_val, val]); handler(val));
}

然后将侦听器设置为:

listen_to(myobj, "a", function(oldval, newval) {
    alert("old : " + oldval + " new : " + newval);
}

其次,我实际上忘记了,我会在考虑的同时提交:)

编辑:哦,我记得:)您可以将手表放在值上:

给定上面的myobj,上面带有“ a”:

function watch(obj, prop, handler) { // make this a framework/global function
    var currval = obj[prop];
    function callback() {
        if (obj[prop] != currval) {
            var temp = currval;
            currval = obj[prop];
            handler(temp, currval);
        }
    }
    return callback;
}

var myhandler = function (oldval, newval) {
    //do something
};

var intervalH = setInterval(watch(myobj, "a", myhandler), 100);

myobj.set_a(2);
Tom小小蛋蛋2020/03/13 18:24:47

抱歉,打了个旧话题,但是对于那些不了解Eli Grey的示例如何工作的人,这里有一些手册:

var test = new Object();
test.watch("elem", function(prop,oldval,newval){
    //Your code
    return newval;
});

希望这可以帮助某人

神奇老丝2020/03/13 18:24:47

是的,现在完全有可能!

我知道这是一个旧线程,但是现在可以使用访问器(获取器和设置器)实现这种效果:https : //developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Working_with_Objects#Defining_getters_and_setters

您可以定义一个这样的对象,其中aInternal代表字段a

x = {
  aInternal: 10,
  aListener: function(val) {},
  set a(val) {
    this.aInternal = val;
    this.aListener(val);
  },
  get a() {
    return this.aInternal;
  },
  registerListener: function(listener) {
    this.aListener = listener;
  }
}

然后,您可以使用以下方法注册侦听器:

x.registerListener(function(val) {
  alert("Someone changed the value of x.a to " + val);
});

So whenever anything changes the value of x.a, the listener function will be fired. Running the following line will bring the alert popup:

x.a = 42;

See an example here: https://jsfiddle.net/5o1wf1bn/1/

You can also user an array of listeners instead of a single listener slot, but I wanted to give you the simplest possible example.