Get element height with Vuejs

123,262

Solution 1

The way you are doing it is fine. But there is another vue specific way via a ref attribute.

 mounted () {
   this.matchHeight()
 },
 matchHeight () {
   let height = this.$refs.infoBox.clientHeight;
 }

    <div class="columns">
        <div class="left-column" id="context">
            <p>Some text</p>
        </div>
        <div class="right-column" id="info-box" ref="infoBox"></>
            <img />
            <ul>
                some list
            </ul>
        </div>
    </div>

In this case, since you are just getting the value it really doesn't matter whether you use your original getElementById approach or the vue specific ref approach. However if you were setting the value on the element then it's much better to use the ref approach so that vue understands that the value has changed and won't possibly overwrite the value with the original value if it needs to update that node in the DOM.

You can learn more here: https://vuejs.org/v2/api/#vm-refs

Update

A few people had left comments that the above solution didn't work for them. That solution provided the concepts but not full working code as example, so I have augmented my answer with the code below which demonstrates the concepts.

var app = new Vue({
    el: '#app',
    data: function () {
        return {
            leftColStyles: { },
            lines: ['one', 'two','three']
        }
    },
    methods: {
        matchHeight() {
            var heightString = this.$refs.infoBox.clientHeight + 'px';
            Vue.set(this.leftColStyles, 'height', heightString); 
        }
    },
    mounted() {
        this.matchHeight();
    }

});
.columns{width:300px}
.left-column {float:left; width:200px; border:solid 1px black}
.right-column {float:right; border:solid 1px blue; }
<div id="app">
    <div class="columns">
        <div class="left-column" id="context" v-bind:style="leftColStyles">
            <p>Some text</p>
        </div>
        <div class="right-column" id="info-box" ref="infoBox"> 
            <img />
            <ul>
                <li v-for="line in lines" v-text="line"></li>
            </ul>
        </div>
    </div>

</div>

 <script src="https://unpkg.com/[email protected]/dist/vue.min.js"></script>
 

Here is a screenshot of the results in the browser:

enter image description here

Note:
My answer assumes that you are loading vue.js from a cdn or locally into the browser and executing it there. If instead you are running your code via the cli and my answer is not working for you, please see @mayank1513's answer instead.

Solution 2

Took a lot of time ⌚ resolving the issue. Initially I tried to follow answer by Ron C. Trying to get this.$refs.infoBox.clientHeight; just didn't work - it gave undefined.

Then I explored the this.$refs.infoBox object.

Wow!!! I don't know how the code he wrote works for him and all others, but there wasn't any property called clientHeight. Finally got it inside $el.

so we need to replace this.$refs.infoBox.clientHeight; with this.$refs.infoBox.$el.clientHeight;

This just worked well for me.

Update

While using nuxt this.$refs.infoBox.$el.clientHeight; didn't work. but Ron C's answer works for this case. this.$refs.infoBox.$el.clientHeight; seems to work while using @vue/cli

Solution 3

I would use flexbox to achieve equal height columns https://css-tricks.com/snippets/css/a-guide-to-flexbox/

.container {
   display: flex;
}
.column {
   border: 1px solid;
   padding: 20px;
   width: 150px;
}
<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width, initial-scale=1">
</head>

<body>
    <div class="container">
        <div class="column">
            Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer ac dui sed erat venenatis fermentum. Nulla tempus, magna
            sit amet ornare fringilla, ligula quam faucibus urna
        </div>
        <div class="column">
            Lorem ipsum dolor sit amet, consectetur adipiscing elit.
        </div>
    </div>
</body>
</html>
Share:
123,262
Juliane Blier
Author by

Juliane Blier

Updated on July 09, 2022

Comments

  • Juliane Blier
    Juliane Blier almost 2 years

    I want to get the height of a div in order to make the height of another div matching it. I used the method clientHeight, but It doesn't return me the good value (smaller value). Actually, It seems to return a height before all elements are charged. After some research online, I tried to put a window.load() to delay until everything is charged but it doesn't work as well. Some ideas ?

    mounted () {
      this.matchHeight()
    },
    matchHeight () {
      let height = document.getElementById('info-box').clientHeight
    }
    <div class="columns">
      <div class="left-column" id="context">
      <p>Some text</p>
      </div>
      <div class="right-column" id="info-box">
        <img />
        <ul>
          some list
        </ul>
      </div>
    </div>

  • Juliane Blier
    Juliane Blier almost 7 years
    Thanks, I tried your solution but same problem. I noticed the div containing the list is not taken into account. It only return the height with the image. But the list has a v-if="someVariable", it seems to be the reason, no ?
  • RonC
    RonC almost 7 years
    Whats the problem?
  • Juliane Blier
    Juliane Blier almost 7 years
    That the list is not taken into account. As if it wasn't displayed, but it is.
  • RonC
    RonC almost 7 years
    Is the list generated server side or client side (for example with a v-for)?
  • christopher clark
    christopher clark over 6 years
    This does not work for my navbar. The mounted() height is 49 px. But when I inspect the height in the dom its 110. obviously after everything is loaded. This project only has vue. no other js or nothing else happening on the component or any other component, so clearly mounted() does not run after everything has been built.
  • RonC
    RonC over 6 years
    @christopherclark - I probably should have left a comment letting you know that because of your comment I updated my answer to include full working code.
  • RonC
    RonC about 6 years
    @gman, why did you change my code from a fully working example to three snipits? Only thing really changed is the order the code is presented and the html head and body tags. Seems like the edited version is less useful to people then the original code I provided. Given your reputation, no doubt you had a positive purpose in mind in making the changes...
  • RonC
    RonC over 3 years
    @McWayWeb I approved your edit to add $el but then when I clicked the "Run code snipit" button in the answer it produces this error "Cannot read property 'clientHeight' of undefined". So I'm reverting the edit.
  • RonC
    RonC over 3 years
    What you are seeing is very interesting and baffling to me. McWayWeb recently proposed a change to my answer to add in the $el in the way you suggest. I initially approved that edit but then it broke my answer so that the "Run code snipit" button produces this error "Cannot read property 'clientHeight' of undefined". So I reverted the edit, and it now works again. I really curious, when you click the "Run code snipit" button in my answer, does it run without error and are the two boxes the same height?
  • mayank1513
    mayank1513 over 3 years
    I run it on my machine with the latest vue and vue-cli
  • RonC
    RonC over 3 years
    Very interesting. I just updated my answer to use the latest version of vue, 2.6.12, it was using 2.2.5, and the answer still works when you click the "Run code snipit" button. So maybe there is a difference between running the code via the cli vs in the browser? Pretty odd.
  • mayank1513
    mayank1513 over 3 years
    Please try with vue cli 4.0+. I needed answer that works for my website and I mentioned what worked for me and what did not. I don't know how it works on this snippet. To be specific I was using firefox browser developer tools and vue devtools as well
  • RonC
    RonC over 3 years
    I wasn't being critical. Just trying to understand. I don't use the cli, in my case I load vue as a js file from a cdn and it runs in the browser. May takeaway from this is that your answer is the one people need if using the cli and my answer is the one they need if loading vue as a js file from a cdn or locally. It's good to have both answers here.
  • mayank1513
    mayank1513 over 3 years
    May be. Will try to verify that and update my answer once I get enough time. Thanks for the discussion.
  • RonC
    RonC over 3 years
    No need, I think the comments here and the two answers will lead people to the one that will work for them.
  • shabushabu
    shabushabu about 3 years
    It shouldn't have anything to do with vue-cli, but with where you add the ref to. Is it a Vue component, then the ref points to the component itself, which has an $el property. If the ref is placed on a regular HTML tag, then there is no Vue component, so the ref points directly to the HTML element.
  • trainoasis
    trainoasis about 3 years
    How can you access refs of child components?
  • RonC
    RonC about 3 years
    @trainoasis - That's a great question which should be asked as it's own StackOverflow questions.