Element height from within an AngularJS directive

14,051

Solution 1

You need to wait till the next digest cycle. When you do it right away in the directive the interpolations {{ ::lbl }} inside the ng-repeat would not have expanded yet. You can place it in a $timeout turning off the applyDigest argument.

i.e, example:

angular.module('heightApp').directive('reportMyHeight', function($timeout) {
   return function (scope, el, attrs) {

      $timeout(init, false);

      //Initialization
      function init(){
        console.log('offsetHeight = ' + el[0].offsetHeight,  el.html());
      }

    }
});

Plnkr

Solution 2

Another way to make sure you get the height of the element is to use watch.

angular.module('heightApp').directive('reportMyHeight', function($timeout) {
  return function (scope, el, attrs) {
    scope.$watch('lbl', function(newval, oldval){
      alert(newval + '\n\n' + 'offsetHeight = ' + el[0].offsetHeight);
    });
  }
})

It will only be triggered once since you use ::.

Share:
14,051
Charles Sounder
Author by

Charles Sounder

Updated on June 21, 2022

Comments

  • Charles Sounder
    Charles Sounder almost 2 years

    I'm trying to get the height of elements in a simple AngularJS app. See below. What am I doing wrong? The height should be different as the lines wrap, but I get 20 reported back to me regardless of what I input in the "labels" array.

    The following code can be executed here, otherwise see below. http://js.do/code/49177

    <!doctype html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <base href="/">
    
      <title>height of element in angularjs</title>
    
      <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css">
    
      <script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.8/angular.js"></script>
      <script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.8/angular-route.js"></script>
      <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
    
      <script type="text/javascript">
        'use strict';
    
        var app = angular.module('heightApp', ['ngRoute', 'routing']);
    
        app.controller('heightCtrl', ['$scope', function ($scope) {
          $scope.labels = [
            'Hi there, I\'m a div.',
            'Me too, I\'m also a div.',
            'Can you see me, because I certainly can\'t see myself. I don\'t even know my own height. Isn\'t that just crazy?'
          ];
    
        }]);    
    
        angular.module('routing', []).config(['$routeProvider', function($routeProvider) {
          $routeProvider
            .when('/', {
              templateUrl: 'height.html',
              controller: 'heightCtrl'
            });
        }]);
    
        angular.module('heightApp').directive('reportMyHeight', function() {
          return function (scope, el, attrs) {
              alert('offsetHeight = ' + el[0].offsetHeight);
            }
        })
      </script>
    
    </head>
    
    <body ng-app="heightApp">
    
    <div class="container">
      <div ng-view></div>
    </div>
    
    </body>
    
    <script type="text/ng-template" id="height.html">
      <div class="row">
        <div class="col-sm-4" report-my-height ng-repeat="lbl in labels">
          {{ ::lbl }}
        </div>
      </div>
    </script>
    
    </html>
    
  • dball
    dball almost 9 years
    $timeout was clutch! I couldn't figure out why the height was so much different than what I was looking at.