简体   繁体   中英

How can I subscribe (or observe) the DOM window and callback upon any changes; not just for window resize events, scroll events, etc.?

I'm trying to watch the window object for changes to any of it's properties and trigger an event whenever any properties change.

For example: window.addEventListener('windowPropertiesChanged', () => {/* do something */})

Can this be implemented with some kind of subscription or observer (mutation observer)? Is there a best practice for doing this?

Thanks in advance for your help.

Very interesting.... how about shadowing the window object for your entire code and replacing it with a proxy?

let windowProxy = new Proxy (window, {
  get: function (target, prop) {
    console.log('Getting', target, prop);

    return target[prop];
  },

  set: function (target, prop, value) {
    console.log('Setting', target, prop);
    // Dispatch event here.

    target[prop] = value;

    return true;
  }
});

(() => {
    let window = windowProxy;

  // ALL YOUR CODE HERE

  window.scrollX = 5; // Setting Window ... scrollX
  console.log(window.scrollX); // Getting Window ... scrollX 5

})()

Or a bit hacky but I guess you could define getters and setters in the window object. It works somehow. This should catch all changes made from js (eg also from plugins etc)

let fakeWindow = {};

for (let key of Object.keys(window)) {
  let descriptor = Object.getOwnPropertyDescriptor(window, key);

  if (!descriptor.configurable) {
        continue;
  }

  fakeWindow[key] = window[key];

  Object.defineProperty(window, key, {  
    set: function (value) {
      console.log('Setting', key, value);
      fakeWindow[key] = value;

      return true;  
    },

    get: function () {
      return fakeWindow[key];
    }
  });
}

console.log(window.scrollX); // 0
window.scrollX = 5; // Setting scrollX 5
console.log(window.scrollX); // 5

EDIT: I just realized you probably want to track all internal changes made from the browser. I think your only option is manually looking for changes at a given interval.

let windowCopy = {};

for (let key of Object.keys(window)) {
    windowCopy[key] = window[key];
}

function check() {
  for (let key of Object.keys(window)) {
    if (window[key] != windowCopy[key]) {
      console.log('Changed', key, window[key]);
      windowCopy[key] = window[key];
    }
  }
}

setInterval(check, 100);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM