Pablo
Pablo

Reputation: 13580

Why are the width and height of a element directive calculated as 0?

On a project I'm currently working on, I have directives with restrict: 'E'.

At some point in my app, I need to know the hight of one of these directives but no matter how I try to determine the width and height of the directive, I always get 0.

I've found some similar questions, but the solutions didn't help as the questions were primarily about finding the height/height of $element inside the directive controller/linker. In my case, the code that tries to find out the dimensions is outside of the directive-linker. In fact, the directives have been already inserted in the DOM for a while.

The code looks like this:

// the directive
app.directive("widget", function() {
    return {
        restrict: 'E',
        transclude: true,
        scope: {
            config: "="
        },
        ....
    };
});
<!-- the view -->
<widget config="config" ng-attr-id="{{ config.id }}"></widget>

And this is the function that tries to get the dimensions of that widget directive

function widget_dimensions(id)
{
    var $w = $('#' + id);

    if($w.length != 1)
        return;

    return {
        width: $w.width(),
        height: $w.height(),
    };
}

This function always returns { width: 0, height: 0} when I pass a real widget id.

I prepared a jsfiddle example that demonstrates this. The directives are already in the DOM. The only function that returns a non-0 on the element directive is getBoundingClientRect(), but here the height is 68.9px and it should be 50px.

Why is this happening? I've read the $compile documentation a few times, hoping to find something that I've missed before.

I use google-chrome Version 67.0.3396.87 for linux. I tested my jsfiddle example on Chromium 57.0.2987.98 and Vivaldi 1.15.1147.47 and I got the same results. However the same test on Firefox 60.0.2 yields the correct result. Is this a bug in chrome family of browsers? Or is it a webkit/blink problem?

EDIT

As Lex points out in the comments, this might not have anything to do with angular after all. I've updated my jsfiddle example which now prints the display property.

Now chrome and firefox say

$d1.css("display"): block
$d2.css("display"): inline

It's interesting that <dtest2></dtest2> is an inline element even though it behaves like a block element. Still, chrome and firefox behave differently when it comes to calculating the dimensions. Which one is correct?

Upvotes: 2

Views: 642

Answers (1)

Petr Averyanov
Petr Averyanov

Reputation: 9476

As being said adding 'display: block' fix all issues, and in both firefox and chrome you get 52px (Cause borders are also counted).

Problems without 'display: block' is related to fact that you should not put block (i.e. div) inside inline (i.e. span).

P.S. you can use clientWidth, clientHeight instead of this pretty getBoundingClientRect. you can see same height and width in dev console. you should not use jquery and methods like function(id) in angular app

Upvotes: 1

Related Questions