Spleenboy Spleenboy - 3 months ago 37
Javascript Question

Get Height for multiple elements without JQuery in AngularJS

Fairly new to Angular and still trying to wrap my head around a few things.
I need to get the height of multiple items on a dashboard. I have seen this answer:
Get HTML Element Height without JQuery in AngularJS
However, I can't work out how to get it to work for multiple items. Surely I don't need to write a separate directive for each element.
So playing with this Plunker, I changed the html to below, but get identical values for both elements.

hmm

script.js:

angular.module('myModule', [])
.directive('myDirective', function($timeout) {
return {
restrict: 'A',
link: function(scope, element) {
scope.height = element.prop('offsetHeight');
scope.width = element.prop('offsetWidth');
}
};
})
;


and the html:

<!DOCTYPE html>
<html>

<head>
<script data-require="angular.js@*" data-semver="1.2.13" src="http://code.angularjs.org/1.2.13/angular.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>

<body ng-app="myModule">

<h1 my-directive>Hello Plunker! width: {{width}}, height: {{height}}
</h1>
<h3 my-directive>Smaller Hello Plunker! width: {{width}}, height: {{height}}
</h3>
</body>

</html>

Answer

The directives have no scope, so they are storing the values on $rootScope. The values reflect the height and width of the last directive to execute. Fix your directive to use either inherited scope or isolate scope.

angular.module('myModule', [])
  .directive('myDirective', function($timeout) {
    return {
        restrict: 'A',
        //set scope to inherited
        scope: true,
        //OR use isolate scope
        //scope: {},
        link: function(scope, element) {
            scope.height = element.prop('offsetHeight');
            scope.width = element.prop('offsetWidth');
        }
    };
  })
;

By setting the scope property, the $compile service will create a new scope (either inherited or isolate) for the directive to store values unique to the directive.

For more information on directive scopes, see AngularJS Comprehensive Directive API -- scope.

Comments