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:
Not use the features they don't have, or
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
Why Does JavaScript Handle the Plus and Minus Operators Between Strings and Numbers Differently
Array.Fill(Array) Creates Copies by References Not by Value
Using "Object.Create" Instead of "New"
Youtube Iframe API: How to Control an Iframe Player That's Already in the HTML
How to Get the Scrollbar Position with JavaScript
JavaScript % (Modulo) Gives a Negative Result for Negative Numbers
Check/Uncheck Checkbox with JavaScript
Comparing Date Part Only Without Comparing Time in JavaScript
How to Check If a Checkbox Is Checked
How to Access Iframe Elements with JavaScript
Prevent Execution of Parent Event Handler
Primitive Value VS Reference Value
JavaScript Regex - Look Behind Alternative
Insert HTML at Caret in a Contenteditable Div
Webdriver Click() VS JavaScript Click()
Stop Execution of JavaScript Function (Client Side) or Tweak It