Skip to content

Instantly share code, notes, and snippets.

@abernier
Last active August 29, 2015 14:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save abernier/c3b9584d63bfd802e08f to your computer and use it in GitHub Desktop.
Save abernier/c3b9584d63bfd802e08f to your computer and use it in GitHub Desktop.
watchcss

Watch a DOM element for [style] css properties changes.

It uses MutationObserver internally

Synopsis

new Watchcss(el, ['propA', 'propB', ...])
  .observe()
  .disconnect()
  .on('change', function (changes) {})
  .on('change:propA', function (change) {})

Usage

var el = document.getElementById('foo');

var watchcss = new Watchcss(el, ['transform-origin', 'border-radius']);

watchcss.on('change', function (changes) {
  console.log('transform-origin OR border-radius have changed!', changes);
});

outputs:

[
  {
    propName: 'transform-origin',
    oldValue: 'center center',
    newValue: 'left center'
  },
  {
    propName: 'border-radius',
    oldValue: '3px',
    newValue: '10px'
  }
]

or with a single property:

watchcss.on('change:transform-origin', function (change) {
  console.log('transform-origin has changed!', change);
});

outputs:

{
  propName: 'transform-origin',
  oldValue: 'center center',
  newValue: 'left center'
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>
#foo {
transform-origin:center center;
}
</style>
</head>
<body>
<div id="foo"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.7.0/underscore.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.1.2/backbone.js"></script>
<script src="https://code.jquery.com/jquery-2.1.3.js"></script>
<script src="watchcss.js"></script>
<script>
var el = document.getElementById('foo');
var watchcss = new Watchcss(el, ['transform-origin', 'border-radius']);
watchcss.on('change', function (changes) {
console.log('transform-origin OR border-radius have changed!', changes);
});
setTimeout(function () {
el.style.transformOrigin = 'left center';
}, 1000)
</script>
</body>
</html>
{
"name": "watchcss",
"version": "0.0.0",
"description": "Watch a DOM element for `[style]` css properties changes",
"main": "watchcss.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "https://gist.github.com/c3b9584d63bfd802e08f.git"
},
"author": "Antoine BERNIER (abernier)",
"license": "ISC",
"dependencies": {
"underscore": "^1.7.0",
"backbone": "^1.1.2",
"jquery": "^2.1.3"
}
}
;(function () {
var _ = this._ || require('underscore');
var $ = this.jQuery || require('jquery');
var Backbone = this.Backbone || require('backbone');
Backbone.$ = $;
function Watchcss(el, props) {
this.el = el;
props || (props = []);
this.props = props;
var propsModel = new (Backbone.Model.extend())(_.object(props, [""]));
var propschanges = [];
propsModel.on('change', function (model) {
_(model.changed).each(function (val, propName) {
propschanges.push({
propName: propName,
oldValue: model._previousAttributes[propName],
newValue: val
});
});
});
this.mo = new MutationObserver(function (muts) {
var i = muts.length;
while (i--) {
if (muts[i].attributeName !== 'style') continue; // only style mutation
propschanges = []; // empty
var mut = muts[i];
var j = this.props.length;
while (j--) {
var prop = this.props[j];
propsModel.set(prop, mut.target.style[prop]);
}
// 'change' event
if (propschanges.length) {
this.trigger('change', propschanges);
// 'change:<prop>' event
var l = propschanges.length;
while (l--) {
var propchange = propschanges[l];
this.trigger('change:'+propchange.propName, propchange);
}
}
}
}.bind(this));
this.observe();
}
_.extend(Watchcss.prototype, Backbone.Events);
Watchcss.prototype.observe = function () {
this.mo.observe(this.el, {attributes: true});
return this;
};
Watchcss.prototype.disconnect = function () {
this.mo.disconnect();
return this;
};
window.Watchcss = Watchcss;
$.fn.watchcss = function (props) {
props || (props = []);
var $el = this;
var instance = $el.data('watchcss');
if (instance) {
instance.props = _.uniq(instance.props.concat(props));
} else {
instance = new Watchcss($el[0], props);
$el.data('watchcss', instance);
}
return instance;
}
}).call(this);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment