Object.Watch() for All Browsers

Object.watch() for all browsers?

(Sorry for the cross-posting, but this answer I gave to a similar question works fine here)

I have created a small object.watch shim for this a while ago. It works in IE8, Safari, Chrome, Firefox, Opera, etc.

Watch for object properties changes in JavaScript

I have created a small object.watch shim for this a while ago. It works in IE8, Safari, Chrome, Firefox, Opera, etc.

/*
* object.watch v0.0.1: Cross-browser object.watch
*
* By Elijah Grey, http://eligrey.com
*
* A shim that partially implements object.watch and object.unwatch
* in browsers that have accessor support.
*
* Public Domain.
* NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
*/

// object.watch
if (!Object.prototype.watch)
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]) { // can't watch constants
if (Object.defineProperty) // ECMAScript 5
Object.defineProperty(this, prop, {
get: getter,
set: setter
});
else if (Object.prototype.__defineGetter__ && Object.prototype.__defineSetter__) { // legacy
Object.prototype.__defineGetter__.call(this, prop, getter);
Object.prototype.__defineSetter__.call(this, prop, setter);
}
}
};

// object.unwatch
if (!Object.prototype.unwatch)
Object.prototype.unwatch = function (prop) {
var val = this[prop];
delete this[prop]; // remove accessors
this[prop] = val;
};

How to maintain similar behaviour among all browsers?

Object.assign was defined by ES2015. Browsers released before that (and probably relatively soon after it) won't have it. That includes all versions of IE, for instance.

This particular function can be polyfilled; I quote MDN's polyfill for it below.

In the general case: If you need to support older browsers that don't have modern features (and many of us do), you need to either:

  1. Not use the features they don't have, or

  2. Use polyfills and transpilers (like Babel) to convert your source code using those features into something that will run on old browsers that don't support them.

Here's that polyfill as of this writing (I just fixed two minor errors in it):

if (typeof Object.assign != 'function') {
  // Must be writable: true, enumerable: false, configurable: true
  Object.defineProperty(Object, "assign", {
  value: function assign(target, varArgs) { // .length of function is 2
    'use strict';
    if (target == null) { // TypeError if undefined or null
      throw new TypeError('Cannot convert undefined or null to object');
    }

    var to = Object(target);

    for (var index = 1; index < arguments.length; index++) {
      var nextSource = arguments[index];

      if (nextSource != null) { // Skip over if undefined or null
        for (var nextKey in nextSource) {
// Avoid bugs when hasOwnProperty is shadowed
          if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
            to[nextKey] = nextSource[nextKey];
          }
        }
      }
    }
    return to;
  },
  writable: true,
  configurable: true
  });
}

How to watch complex objects and their changes in JavaScript?

As @Booster2ooo mention you can use Proxy object to observe the changes, you can use something like this:

function proxify(object, change) {
// we use unique field to determine if object is proxy
// we can't test this otherwise because typeof and
// instanceof is used on original object
if (object && object.__proxy__) {
return object;
}
var proxy = new Proxy(object, {
get: function(object, name) {
if (name == '__proxy__') {
return true;
}
return object[name];
},
set: function(object, name, value) {
var old = object[name];
if (value && typeof value == 'object') {
// new object need to be proxified as well
value = proxify(value, change);
}
object[name] = value;
change(object, name, old, value);
}
});
for (var prop in object) {
if (object.hasOwnProperty(prop) && object[prop] &&
typeof object[prop] == 'object') {
// proxify all child objects
object[prop] = proxify(object[prop], change);
}
}
return proxy;
}

and you can use this fuction like this:

object = proxify(object, function(object, property, oldValue, newValue) {
console.log('property ' + property + ' changed from ' + oldValue +
' to ' + newValue);
});

...

Use Object.watch() on an independent variable?

The global scope in a browser is actually the window object, so if your variable is a global variable, it's actually attached to the window object. So you can access it as window.variableName just as well as simply variableName. And thus you should be able to say:

window.watch('variableName', callback);

How to subscribe to object changes?

Have you tried using Proxy from ECMA6? I think this is what you are looking for
You only have to define a function as the set of the validator of the Proxy like this:

let validator = {
set: function(target, key, value) {
console.log(`The property ${key} has been updated with ${value}`);
return true;
}
};
let store = new Proxy({}, validator);
store.a = 'hello';
// console => The property a has been updated with hello

running specific code in js file pertaining to i.e9 v's all other browsers

You can use conditional comments in html:

<!--[if lte IE 9]>
// Include script for ie9 and less here
<![endif]-->

Update:

You can use navigator object in Script to detect if it is ie9 or below.

navigator.appVersion

It return this:

clientVersion (platform; information; extraInformation)

example:

5.0 (compatible; MSIE 5.5; Windows 98; Win 9x 4.90)

Check the following link

Here is the code:

var flag = false;
function getInternetExplorerVersion()
// Returns the version of Internet Explorer or a -1
// (indicating the use of another browser).
{
var rv = -1; // Return value assumes failure.
if (navigator.appName == 'Microsoft Internet Explorer')
{
var ua = navigator.userAgent;
var re = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
if (re.exec(ua) != null)
rv = parseFloat( RegExp.$1 );
}
return rv;
}
function checkVersion()
{
var msg = "You're not using Internet Explorer.";
var ver = getInternetExplorerVersion();

if ( ver > -1 )
{
if ( ver == 9.0 )
flag = true
else
flag = false
}else{
flag = false
}
}

Now check in you function if flag is true call the function else jump through

Update 3:

var ms_ie = false;
var ua = window.navigator.userAgent;
var old_ie = ua.indexOf('MSIE ');
var new_ie = ua.indexOf('Trident/');

if ((old_ie > -1) || (new_ie > -1)) {
ms_ie = true;
}

if ( ms_ie ) {
//IE specific code goes here
}

Try this code

$('.fa-phone, .bg-darkPink').parent().on('click', function () {
$('.submenu-ctn').fadeTo(0, 0);
$('.submenu-ctn').fadeTo(3000, 1);
$("#colorscreen").remove();
$("body").append('<div id="colorscreen" class="animated"></div>');
$("#colorscreen").addClass("fadeInUpBigCS");
$(".tile-area-main").css({width: "720px",opacity:1}).load("contact-page.html #contact-form");
$.getScript("js/slider/slider-animations.js");
$(".submenu-ctn").load("contact-page.html .submenu-contact");
$('.nav-toggle').removeClass('active');
$(this).addClass('active');

// code started here

var ms_ie = false;
var ua = window.navigator.userAgent;
var new_ie = ua.indexOf('Trident/5'); //only for ie9

if ((new_ie > -1) {
ms_ie = true;
}

if ( ms_ie ) {
$('#menu').multilevelpushmenu({Collapsed: true});
}else{
$( '#menu' ).multilevelpushmenu( 'collapse' );
}
});

Angular2 watch object/array changes (Angular2 final = 2.1.1)

Angular2 provides IterableDiffer (array) and KeyValueDiffer (object) to get information about differences between two checks.

NgClass is a good example https://github.com/angular/angular/blob/14ee75924b6ae770115f7f260d720efa8bfb576a/modules/%40angular/common/src/directives/ng_class.ts#L122

See also https://angular.io/docs/ts/latest/api/#!?query=differ

An example

// inject a differ implementation 
constructor(differs: KeyValueDiffers) {
// store the initial value to compare with
this.differ = differs.find({}).create(null);
}

@Input() data: any;

ngDoCheck() {
var changes = this.differ.diff(this.data); // check for changes
if (changes && this.initialized) {
// do something if changes were found
}
}


Related Topics



Leave a reply



Submit