首页  >  文章  >  web前端  >  弃用 Object.watch() 后,我还能跨浏览器监视对象更改吗?

弃用 Object.watch() 后,我还能跨浏览器监视对象更改吗?

DDD
DDD原创
2024-10-28 22:04:30996浏览

 Can I Still Monitor Object Changes Across Browsers After Object.watch() Was Deprecated?

使用Object.watch()进行跨浏览器对象变化监控

问题:有没有办法监控尽管已弃用 Object.watch(),但对象在多个浏览器中一致变化?

来自“pseudoecstatic”的回答:

是的,我开发了一个简单的 Object.watch () shim 可在 IE8、Safari、Chrome、Firefox、Opera 和其他流行浏览器中无缝运行。

实现:

在您的项目中包含以下 shim:

<code class="javascript">(function () {
  var toString = Object.prototype.toString,
    isNative = function (obj) {
      return toString.call(obj) === '[object Object]';
    },
    attachListener = function (target, prop, fn) {
      target.__watchers__ || (target.__watchers__ = {});
      target.__watchers__[prop] || (target.__watchers__[prop] = []);
      target.__watchers__[prop].push(fn);
    },
    detachListener = function (target, prop, fn) {
      if (target.__watchers__ && target.__watchers__[prop]) {
        var watchers = target.__watchers__[prop];
        for (var i = 0; i < watchers.length; i++) {
          if (watchers[i] === fn) {
            watchers.splice(i, 1);
            if (watchers.length === 0) {
              delete target.__watchers__[prop];
            }
            break;
          }
        }
      }
    },
    getWatchers = function (target, prop) {
      if (target.__watchers__ && target.__watchers__[prop]) {
        return target.__watchers__[prop];
      }
      return [];
    },
    notifyWatchers = function (target, prop, oldValue, newValue) {
      var watchers = getWatchers(target, prop);
      for (var i = 0; i < watchers.length; i++) {
        try {
          var newval = watchers[i](prop, oldValue, newValue);
          if (isNative(newval)) {
            newValue = newval;
          }
        } catch (e) {
          setTimeout(function () {
            throw e;
          }, 0);
        }
      }
      return newValue;
    },
    convert = function (prop, fn, target, rec) {
      var orig = target[prop];
      Object.defineProperty(target, prop, {
        configurable: true,
        enumerable: true,
        get: function () {
          return orig;
        },
        set: function (value) {
          if (orig !== value) {
            var oldval = orig;
            orig = notifyWatchers(target, prop, orig, value);
            fn(prop, oldval, orig, target);
          }
        }
      });
      if (rec && isNative(orig)) {
        for (var subprop in orig) {
          convert(subprop, fn, orig, rec);
        }
      }
    },
    watch = function (target, prop, fn, rec) {
      if (!target || typeof prop !== 'string' || typeof fn !== 'function') {
        throw new Error('Bad arguments');
      }
      attachListener(target, prop, fn);
      fn(prop, target[prop], target[prop], target);
      if (rec && isNative(target[prop])) {
        for (var p in target[prop]) {
          convert(p, fn, target[prop], true);
        }
      }
    },
    unwatch = function (target, prop, fn) {
      if (!target || typeof prop !== 'string') {
        throw new Error('Bad arguments');
      }
      detachListener(target, prop, fn);
    },
    constrained = function (val, defval) {
      if (val !== null && val !== undefined) {
        return val;
      } else {
        return defval;
      }
    },
    watchEvery = function (obj, fn, rec) {
      rec = constrained(rec, false);
      for (var p in obj) {
        convert(p, fn, obj, rec);
      }
    },
    stopWatchingEvery = function (obj, fn) {
      for (var p in obj) {
        unwatch(obj, p, fn);
        delete obj.__watchers__[p];
      }
    };
  Object.watch = watch;
  Object.unwatch = unwatch;
  Object.watchEvery = watchEvery;
  Object.stopWatchingEvery = stopWatchingEvery;
})();</code>

用法:

您现在可以按如下方式使用 Object.watch() shim:

<code class="javascript">var options = {'status': 'no status'},
watcher = Object.watch(options, 'status', function (prop, oldValue, newValue) {
  // Do something with the change...
});

watcher.status = 'asdf';
watcher.status = '1234';</code>

Cross -浏览器兼容性:

此填充程序可确保 Object.watch() 功能在所有主要浏览器中保持一致,包括那些本身不支持它的浏览器。

以上是弃用 Object.watch() 后,我还能跨浏览器监视对象更改吗?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn