Discussion
Discussion copied to clipboard
Get height of element AFTER the page is done loading
So this is my current dilemna:
http://jsfiddle.net/59yp3r4h/
If you look at the Fiddle, the height gets cut off (line 81 in the javascript). If you hit run, it gets it fine. I have to do a setTimeout with a 10 milisecond timeframe to get the height of the element. This looks terrible.. I thought the attached method and ready method waited until $el was available.. It's getting the wrong height because it's not loading fast enough or something.
What's a workaround for this BESIDES the setTimeout? The element is available at that time, but the height isn't available yet. It SAYS 129 pixels when I do a console.log(this.$el), but whenever I do this.$el.clientHeight, it says 76. Even though it says 129 when I look through that first console log. This makes no sense..
I'm having this issue in multiple places that I need to get the dimensions. Vue works great functionality wise, but this issue is starting to drag my work down at my workplace and personal projects. I feel like I shouldn't be using Vue because of this. I have to mess with the dimensions a LOT for my components.
Thanks for any help.
Figured it out. I ended up creating a mixin that issued window.onload() and called the callback function that was passed into it! So I would create a method in my methods section inside my component where everything that needed to be fired on window load would be in that method. Then on the attached() method, I just called this.onPageLoad( this.callBackFunction ). Only thing that I could see as a workaround for now.
EDIT: use the solution below.
// In your component or mixin:
created () { // would work in 'ready', 'attached', etc.
window.addEventListener('load', () => {
// https://developer.mozilla.org/en-US/docs/Web/API/CSS_Object_Model/Determining_the_dimensions_of_elements
console.log(this.$el.clientHeight)
})
}
ready() {
this.$nextTick(() => {
console.log(this.$el.clientHeight);
});
}
In Vue2.0 the above code by @pbelyaev isn't working anymore.
Anymore ideas besides listening to window onload ?
In Vue 2.x, ready was replaced by mounted.
mounted () {
this.$nextTick(() => {
console.log(this.$el.clientHeight)
})
}
@elcontraption Yes I am aware of that. Sorry should have made it clear in the beginning.
But it still didn't work. I tested on mounted() and updated() (I think updated() gets fired one time after the component is mounted) method, and both returned the wrong clientHeight.
@pxwee5 try a reduced test case? https://codepen.io/elcontraption/pen/eEbvRp/.
@elcontraption That's weird.
Let me check the code, maybe it's to do with the images not loaded yet during mount.
@pxwee5
If you use style-loader(That use with blob:http to load css, it seems asynchronous ) instead of vue-style-loader(use
In the dev mode, because we not use extract-text-webpack-plugin, the style is add when the component init, so the style of the component is not ready in the mounted hook...
It is not a problem in the 'production' with extract-text-webpack-plugin, so we can just do something to fix this in dev mode:
Vue.mixin({
methods: {
$ready(fn) {
if (process.env.NODE_ENV === 'production') {
return this.$nextTick(fn);
}
setTimeout(() => {
this.$nextTick(fn);
});
}
}
});
and use in the mounted hook:
mounted() {
this.$ready(() => {
// here the style is ready
})
}
@ccqgithub -- thank you. i was struggling even with $nextTick to find the offsetWidth of a flexbox element upon being mounted. this mixin helped.
@ccqgithub's solution worked for me, too... but I had to configure setTimeout to wait a second (second parameter).
Vue.mixin({
methods: {
$ready(fn) {
if (process.env.NODE_ENV === 'production') {
return this.$nextTick(fn)
}
setTimeout(() => {
this.$nextTick(fn)
}, 1000)
},
},
})
I also run into this problem, any updates?
I am also facing this problem when using $nextTick inside a mixin. My intention was to wait for all child components to be ready in order to bind some elements using an third party library.
When I used this approach directly on a component, I have not found any errors. But it never worked once extracted into a mixin.
I had a similiar problem (however, mine was IE specific and clientWidth, but still on the mounted() lifecycle call).
So, for some reason, it helped referencing it twice.
Since my initial value was 0 I could do something like this:
var width = this.$el.clientWidth || this.$el.clientWidth;
I ran across this when I tried to debug it and the bug would disappear if I logged the clientWidth via console.log before I used it.
Maybe this helps someone! Sorry if it doesn't!