是否有可能在JS中有一个事件,当某个变量的值发生变化时触发?JQuery被接受。
当前回答
这个问题是关于变量的,而不是对象属性!因此,我的方法是利用窗口对象及其自定义getter /setter,然后像“正常”变量(不像对象属性)一样使用/更改变量。
最简单的方法是@José Antonio Postigo在他的回答中(我投票了那个答案)。我在这里想做的是将其简化为一个更简单的“creator”函数(这样即使不理解对象getter /setter的人也可以轻松使用它)。
一个活生生的例子在这里:https://codepen.io/dimvai/pen/LYzzbpz
这是你必须拥有的一般“creator”函数:
let createWatchedVariable = (variableName,initialValue,callbackFunction) => {
// set default callback=console.log if missing
callbackFunction ??= function(){console.log(variableName+" changed to " + window[variableName])};
// the actual useful code:
Object.defineProperty(window, variableName, {
set: function(value) {window["_"+variableName] = value; callbackFunction()},
get: function() {return window["_"+variableName]}
});
window[variableName]=initialValue??null;
};
然后,不要使用var或let来声明变量,而是使用下面的语句:
// 1st approach - default callback//
createWatchedVariable ('myFirstVariable',12);
// instead of: let myFirstVariable = 12;
或者,为了使用你的自定义回调(而不是默认的console.log)使用:
// 2nd approach - set a custom callback//
var myCallback = ()=>{/*your custom code...*/}
// now use callback function as the third optional argument
createWatchedVariable('mySecondVariable',0,myCallback);
就是这样!现在,你可以像改变一个“正常”变量一样改变它:
myFirstVariable = 15; // logs to console
myFirstVariable++; // logs to console
mySecondVariable = 1001; // executes your custom code
mySecondVariable++; // executes your custom code
其他回答
我搜索了JavaScript双向数据绑定库,发现了这个库。
我没有成功地使它在DOM到变量的方向上工作,但在变量到DOM的方向上它是工作的,这就是我们在这里需要的。
我稍微重写了一下,因为原始代码(对我来说)很难阅读。它使用 object。defineproperty,这是Eliot b给出的第二多赞的答案,至少有部分错误。
<!DOCTYPE html>
<html>
<head>
<title>TODO supply a title</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script>
const dataBind = (function () {
const getElementValue = function (selector) {
let element = document.querySelectorAll(selector)[0];
return 'value' in element ? element.value : element.innerHTML;
};
const setElementValue = function (selector, newValue) {
let elementArray = document.querySelectorAll(selector);
for (let i = 0; i < elementArray.length; i++) {
let element = elementArray[i];
if ('value' in element) {
element.value = newValue;
if (element.tagName.toLowerCase() === 'select'){
let options = element.querySelectorAll('option');
for (let option in options){
if (option.value === newValue){
option.selected = true;
break;
}
}
}
} else {
element.innerHTML = newValue;
}
}
};
const bindModelToView = function (selector, object, property, enumerable) {
Object.defineProperty(object, property, {
get: function () {
return getElementValue(selector);
},
set: function (newValue) {
setElementValue(selector, newValue);
},
configurable: true,
enumerable: (enumerable)
});
};
return {
bindModelToView
};
})();
</script>
</head>
<body>
<div style="padding: 20%;">
<input type="text" id="text" style="width: 40px;"/>
</div>
<script>
let x = {a: 1, b: 2};
dataBind.bindModelToView('#text', x, 'a'); //data to dom
setInterval(function () {
x.a++;
}, 1000);
</script>
</body>
</html>
JSFiddle.
JSFiddle原始代码。
在提供的示例中,对象x的属性由setInterval更新,文本输入的值也会自动更新。如果这还不够,并且事件是你想要的,你可以在上面的输入中添加onchange监听器。如果需要,输入也可以被隐藏。
我来这里是为了寻找node js的相同答案。就在这里
const events = require('events');
const eventEmitter = new events.EventEmitter();
// Createing state to watch and trigger on change
let x = 10 // x is being watched for changes in do while loops below
do {
eventEmitter.emit('back to normal');
}
while (x !== 10);
do {
eventEmitter.emit('something changed');
}
while (x === 10);
我正在做的是设置一些事件发射器时,值被改变,并使用do while循环来检测它。
这不是一个理想的答案,但它所做的是在JavaScript中每100毫秒设置一个间隔,并检查变量是否被改变,当它被改变时,它会做一些事情(OP想要的任何事情),然后清除间隔,所以它有点模拟OP的要求。
let myvar = "myvar";
const checkChange = setInterval(() => {
if (myvar !== "myvar") {
console.log("My precious var has been changed!");
clearInterval(checkChange);
}
}, 100);
现在,如果myvar被更改为其他东西,那么这个程序会说“我宝贵的var已被更改!”:)
对于那些几年后收听的人来说:
大多数浏览器(和IE6+)都有一个解决方案,它使用onpropertychange事件和更新的规范defineProperty。有一点需要注意的是,您需要将变量设置为dom对象。
详情:
http://johndyer.name/native-browser-get-set-properties-in-javascript/
这就是我所做的:调用JSON。Stringify两次并比较两个字符串…
缺点:
你只能知道整个物体是否发生了变化 您必须手动检测更改 你最好在对象中只有基本字段(没有属性,没有函数……)