Как я могу подписаться (или наблюдать) окно DOM и обратный вызов при любых изменениях; не только для событий изменения размера окна, событий прокрутки и т. д. c. - PullRequest
2 голосов
/ 06 апреля 2020

Я пытаюсь наблюдать за объектом окна на предмет изменения каких-либо его свойств и инициировать событие при каждом изменении каких-либо свойств.

Например: window.addEventListener('windowPropertiesChanged', () => {/* do something */})

Может ли это быть реализовано с какой-то подпиской или наблюдателем (наблюдателем мутаций)? Есть ли лучшая практика для этого?

Заранее спасибо за вашу помощь.

1 Ответ

1 голос
/ 06 апреля 2020

Очень интересно .... как насчет теневого объекта окна для всего вашего кода и замены его прокси-сервером?

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

})()

Или немного странно, но я думаю, вы могли бы определить геттеры и сеттеры в оконный объект. Это работает как-то. Это должно отразить все изменения, сделанные из js (например, также из плагинов и c)

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

РЕДАКТИРОВАТЬ: я только что понял, что вы, вероятно, хотите отслеживать все внутренние изменения, сделанные из браузера. Я думаю, что ваш единственный вариант - вручную искать изменения в заданном интервале.

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);
...