是否有可能在JS中有一个事件,当某个变量的值发生变化时触发?JQuery被接受。
当前回答
@akira和@mo-d-genesis的解决方案可以进一步简化,因为在这个例子中DOM操作不依赖于状态:
CodePen
const render = (val) => {
document.getElementById("numberDiv").innerHTML = val;
};
state = {
_value_internal: undefined,
set value(val) {
// 1. set state value
this._value_internal = val;
// 2. render user interface
render(val);
},
get value() {
return this._value_internal;
},
};
const onClick = () => {
state.value = state.value + 1; // state change leads to re-render!
};
// set default value
state.value = 0;
对应的html:
<div id="numberDiv"></div>
<button onclick="onClick()">
Click to rerender
</button>
备注:
我重命名了变量和函数,以更好地反映它们的语义。 仅供参考:通过改变变量,Svelte提供了非常类似的反应行为
其他回答
不是直接的:你需要一个“addListener/removeListener”接口的一对getter/setter…或者一个NPAPI插件(但这完全是另一个故事)。
No.
但是,如果这真的很重要,你有两个选择(第一个是测试,第二个不是):
首先,使用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);
@akira和@mo-d-genesis的解决方案可以进一步简化,因为在这个例子中DOM操作不依赖于状态:
CodePen
const render = (val) => {
document.getElementById("numberDiv").innerHTML = val;
};
state = {
_value_internal: undefined,
set value(val) {
// 1. set state value
this._value_internal = val;
// 2. render user interface
render(val);
},
get value() {
return this._value_internal;
},
};
const onClick = () => {
state.value = state.value + 1; // state change leads to re-render!
};
// set default value
state.value = 0;
对应的html:
<div id="numberDiv"></div>
<button onclick="onClick()">
Click to rerender
</button>
备注:
我重命名了变量和函数,以更好地反映它们的语义。 仅供参考:通过改变变量,Svelte提供了非常类似的反应行为
如果你正在使用jQuery {UI}(每个人都应该使用:-)),你可以使用.change()和一个隐藏的<input/>元素。
在getter和setter的帮助下,您可以定义一个JavaScript类来做这样的事情。
首先,我们定义一个名为MonitoredVariable的类:
class MonitoredVariable {
constructor(initialValue) {
this._innerValue = initialValue;
this.beforeSet = (newValue, oldValue) => {};
this.beforeChange = (newValue, oldValue) => {};
this.afterChange = (newValue, oldValue) => {};
this.afterSet = (newValue, oldValue) => {};
}
set val(newValue) {
const oldValue = this._innerValue;
// newValue, oldValue may be the same
this.beforeSet(newValue, oldValue);
if (oldValue !== newValue) {
this.beforeChange(newValue, oldValue);
this._innerValue = newValue;
this.afterChange(newValue, oldValue);
}
// newValue, oldValue may be the same
this.afterSet(newValue, oldValue);
}
get val() {
return this._innerValue;
}
}
假设我们想监听钱的变化,让我们创建一个初始值为0的MonitoredVariable实例:
const money = new MonitoredVariable(0);
然后我们可以使用money来获取或设置它的值。
console.log(money.val); // Get its value
money.val = 2; // Set its value
因为我们没有为它定义任何监听器,所以在钱之后没有什么特别的事情发生。Val变成了2。
现在让我们定义一些侦听器。我们有四个可用的侦听器:beforeSet、beforeChange、afterChange、afterSet。 当你使用金钱时,下面的事情会依次发生。val = newValue更改变量的值:
钱。beforeSet (newValue oldValue); 钱。beforeChange (newValue oldValue);(如果它的值没有改变,将被跳过) 钱。val = newValue; 钱。afterChange (newValue oldValue);(如果它的值没有改变,将被跳过) 钱。afterSet (newValue oldValue);
现在我们定义了afterChange监听器,它只会在金钱之后被触发。val已经改变(而afterSet将被触发,即使新值与旧值相同):
money.afterChange = (newValue, oldValue) => {
console.log(`Money has been changed from ${oldValue} to ${newValue}`);
};
现在设置一个新的值3,看看会发生什么:
money.val = 3;
您将在控制台中看到以下内容:
Money has been changed from 2 to 3
完整代码请参见https://gist.github.com/yusanshi/65745acd23c8587236c50e54f25731ab。
推荐文章
- 在数组中获取所有选中的复选框
- 如何为Firebase构建云函数,以便从多个文件部署多个函数?
- 如何发送推送通知到web浏览器?
- AngularJS:工厂和服务?
- js:将一个组件包装成另一个组件
- 父ng-repeat从子ng-repeat的访问索引
- JSHint和jQuery: '$'没有定义
- 模仿JavaScript中的集合?
- 用JavaScript验证电话号码
- 如何在HTML5中改变视频的播放速度?
- 谷歌地图API v3:我可以setZoom后fitBounds?
- 用jQuery检查Internet连接是否存在?
- 如何使用滑动(或显示)函数在一个表行?
- ES6/2015中的null安全属性访问(和条件赋值)
- 与push()相反;