I need to trigger a function whenever window.location.href changes but I'm running into problems. I went over the source for various watch polyfills, but I can't quite follow what was going on with the code.
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
});
}
}
});
}
Obviously, I don't know much about the internals of JS or reflection in general. Here is a method that works for title:
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 });
But I can't specify Location via a query selector and I'm pretty sure it would need to implement the node class for observer to work.
In non-Firefox browsers, you cannot set a watcher on location.href. I needed to set the watcher on location.pathway, location.hash, and location.search instead.
It is also better to just reuse a function instead of writing the same one out twice. I was able to shave it down to just this:
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
});
}
};
}
This is a little bit of a hack, but not much more than anything else I have seen and it will work pretty much equally in all modern browsers.
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);
It simply polls the properties in short intervals. To short to be visible for the user but it should also not have much CPU overhead.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With