如何使用 `MutationObserver` 来观察 `HTMLElement` 的属性而不是属性

时间:2021-07-18 04:58:25

标签: javascript html

使用 MutationObserver.observe(),我可以监听某个属性的变化。例如,如果我有一个 Div,并且属性 value 发生变化,则将调用分配的回调。但是,如果属性(同名)发生更改,则不会调用它:

const observer = new MutationObserver(callback);

divNode = document.getElementById('my-id');

// Start observing the target node for configured mutations
observer.observe(divNode, {attributes: true});

// ...

// This will trigger `callback` to be called
divNode.setAttribute('value', 'something new')

// This will do nothing, since value is a property, not attribute
divNode.value = 'something new'

我相信(但尚未测试)这是一个问题,因为 value 不是 <div> 的“已知”属性,因此当属性更新时 Javascript 不会自动更新关联的属性.

具体聆听divNode.value的最佳方式是什么?

2 个答案:

答案 0 :(得分:2)

我不认为 MutationObserver 可以做到这一点。另一种方法是覆盖 .value getter/setter:

const input = document.querySelector('input');
const { get, set } = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'value');
Object.defineProperty(input, 'value', {
  get() {
    console.log('got');
    return get.call(this);
  },
  set(newVal) {
    console.log('set');
    return set.call(this, newVal);
  }
});

input.value = 'some value';
<input>

但这太奇怪了。我希望永远不要在严肃的代码中看到这种情况,除非您处于一种奇怪的情况,需要观察您无法控制的更改(例如在运行其他人的脚本时)。

答案 1 :(得分:1)

使用代理

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy

function watchPropsOn(el) {
  return new Proxy(el, {
    get(target, propKey, receiver) {
      console.log('get', propKey);
      return el[propKey];
    },
    set(target, propKey, value, receiver) {
      console.log('set', propKey, value);
      target[propKey] = value;
    }
  });
}

let divNode  = document.getElementById('my-id');

let divProxy = watchPropsOn(divNode);
divProxy.value = 'some text';
console.log(divProxy.value);
<input id="my-id">