我有一个使用
setInterval
来检查某些对象状态的脚本,但它会导致一点延迟,我想知道是否可以使用 MutationObserver
?
我的
setInterval
:
var checkExist = setInterval(function() {
var life = 300;
var games = Game.currentGame.ui.playerPetTick.health;
if (games < life) {
console.log("It exists")
clearInterval(checkExist);
}
}, 100); // check every 100ms
我的观察者尝试:
var target = Game.currentGame.ui.playerPetTick.health;
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
console.info("It exists");
});
});
var config = { attributes: true, childList: true, characterData: true };
observer.observe(target, config);
这可以做到吗?
MutationObserver 在这里不会帮助你,因为你的对象似乎不是 DOM 节点。但是您可以使用getters/setters或代理对象轻松实现某种对象观察。一个简单的例子:
var playerInfo = {
set health(newValue) {
this._health = newValue;
if (this.onhealthchange) {
this.onhealthchange(newValue);
}
},
get health() {
return this._health;
}
};
playerInfo.onhealthchange = function(newValue) {
console.info("Health changed: " + newValue);
};
playerInfo.health = 4;
我建议使用 setter 和 getter(MutationObserver,正如我在评论中所写,仅用于 Node 对象)。因为我从你的代码中假设的属性可能是各种类型(对象、字符串等),所以我建议使用 lodash
isEqual
方法 - 它接受数组、对象、字符串、数字等,所以你不需要需要为每种类型编写比较函数。非常方便的功能。
您也可以仅安装此特定功能。
这里我创建了一个函数,您可以在其中传递对象和属性名称以监视更改:
var isEqual = require('lodash.isequal');
function watchChanges(object, prop, primaryValue) {
object[`_${prop}`] = primaryValue;
Object.defineProperty(object, prop, {
get() { return object[`_${prop}`] },
set(newValue) {
if ( !isEqual(object[`_${prop}`] , newValue)) {
console.log('change maded in prop')
}
object[`_${prop}`] = newValue;
},
});
}
为了检查发生了什么,这里有一个基本类型的等效函数:
function watchChanges(object, prop, defaultValue) {
object[`_${prop}`] = defaultValue;
Object.defineProperty(object, prop, {
get() { return object[`_${prop}`] },
set(newValue) {
if ( object[`_${prop}`] !== newValue) {
console.log('change maded in', prop, 'was', object[`_${prop}`], 'is', newValue)
}
object[`_${prop}`] = newValue;
},
});
}
ob = {a: 1, b:1, c:1};
watchChanges(ob, 'a', ob.a);
ob.a = 2;
ob.a = 3;