为window.location附加更改通知程序

时间:2014-03-03 00:27:51

标签: javascript reflection

每当window.location.href发生变化时我都需要触发一个函数,但是我遇到了问题。我查看了各种watch polyfill的来源,但我无法完全按照代码进行操作。

if (!Object.prototype.watch) {
  Object.defineProperty(Object.prototype, "watch", {
    enumerable: false
    , configurable: true
    , writable: false
    , value: function (prop, handler) {
      var
        oldval = this[prop]
        , newval = oldval
        , getter = function () {
          return newval;
        }
        , setter = function (val) {
          oldval = newval;
          return newval = handler.call(this, prop, oldval, val);
        }
        ;
      if (delete this[prop]) { // can't watch constants
        Object.defineProperty(this, prop, {
          get: getter
          , set: setter
          , enumerable: true
          , configurable: true
        });
      }
    }
  });
}

显然,我对JS的内部结构或一般的反思知之甚少。这是一个适用于标题的方法:

var observer = new window.MutationObserver(function(mutations) {
  mutations.forEach(function(mutation) {
    change({title: mutation.target.textContent});
  });
});

observer.observe(document.querySelector('head > title'),
  { subtree: true, characterData: true, childList: true });

但我不能通过查询选择器指定Location,我很确定它需要实现nodever的节点类才能工作。

2 个答案:

答案 0 :(得分:2)

在非Firefox浏览器中,您无法在location.href上设置观察程序。我需要在location.pathwaylocation.hashlocation.search上设置观察者。

最好只重用一个函数,而不是两次写出相同的函数。我能够把它剃成这样:

if (!Object.prototype.watch) { //don't overwrite gecko watch function
  Object.prototype.watch = function(prop, handler) {
    var oldval = this[prop], newval = oldval,
      getter = function() {
        return newval;
      },
      setter = function(val) {
        oldval = newval;
        return newval = handler.call(this, prop, oldval, val);
      };
    if (delete this[prop]) {
      Object.defineProperty(this, prop, {
        get: getter,
        set: setter
      });
    }
  };
}

答案 1 :(得分:0)

这有点像黑客攻击,但并不比我见过的任何东西都多,而且它在所有现代浏览器中的工作方式都相同。

var myTitle = document.title;
var myLocation = window.location.href;

setInterval(function() {
    if (myTitle != document.title || myLocation != window.location.href)
    {
        // Do something here;

        myTitle = document.title;
        myLocation = window.location.href;         
    }
}, 100);

它只是在短时间内轮询属性。要缩短以便用户可见,但它也应该没有太多的CPU开销。