JSFiddle - React, Tailwind, and code Playground
by simonsparks
HTML
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
<div class="fullheight" data-ng-app="app">
<div class="fullheight" data-ng-controller="controller">
<h1>Size Watcher Test</h1>
<p>A demonstration of watching changes to an element's size in AngularJS with a controllable refresh rate.</p>
<h2>
<label for="enabled">Enabled:</label>
<input id="enabled" type="checkbox" data-ng-model="enabled" />
<span>Size:</span>
<strong data-ng-bind="info.width"></strong>
<span>x</span>
<strong data-ng-bind="info.height"></strong>
<span>px</span>
</h2>
<div class="parent">
<div class="directive" data-ng-if="enabled" data-width="info.width" data-height="info.height" data-rate="info.rate">
<div class="wrapper">
<p>Directive enabled with size watcher service.</p>
<p>Updates are reflected in the model of the parent controller, as seen above.</p>
<p>
<label for="rate">Refresh rate (ms):</label>
<input type="number" data-ng-model="info.rate"></input>
</p>
</div>
</div>
</div>
</div>
</div>
CSS
html, body, .fullheight {
height: 100%;
}
.parent {
height: 50%;
width: 50%;
margin: auto;
border: 1px solid;
border-radius: 5px;
}
.directive {
height: 100%;
width: 100%;
}
.wrapper {
margin: 10px;
padding:10px;
}
JavaScript
angular.module('app', [])
.factory('sizeWatcher', ['$interval', function($interval) {
return function (element, rate) {
var self = this;
(self.update = function() { self.dimensions = [element.offsetWidth, element.offsetHeight]; })();
self.group = [function() { return self.dimensions[0]; }, function() { return self.dimensions[1]; }];
self.monitor = $interval(self.update, rate);
self.cancel = function() { $interval.cancel(self.monitor); };
}
}])
.controller('controller', ['$scope', function($scope) {
$scope.enabled = true;
$scope.info = {
width: 0,
height: 0,
rate: 200
};
}])
.directive('directive', ['sizeWatcher', function(sizeWatcher) {
return {
restrict: 'C',
scope: {
width: '=',
height: '=',
rate: '='
},
link: function($scope, element) {
var parent = element[0],
watcher, groupWatcher,
cancel = function() {
if(watcher) watcher.cancel();
if(groupWatcher) groupWatcher();
},
update = function() {
cancel();
watcher = new sizeWatcher(parent, $scope.rate);
$scope.$watchGroup(watcher.group, function(values) {
$scope.width = values[0];
$scope.height = values[1];
});
};
$scope.$watch('rate', update);
$scope.$on('$destroy', cancel);
}
}
}]);