vue-stack-grid
vue-stack-grid copied to clipboard
Horizontal scrollbar is visible on page refresh
I noticed when I refresh the page, I can see a horizontal scrollbar. However, if I resize the browser window it goes away and recalculates the grid items correctly again.
I can easily add an overflow-y: hidden to remove but it's not really a solution as the right side items will be cutoff and not fully shown.
I also tried adding:
ref="stacker"
and then a button to call a method:
<b-button @click="reflow">reflow</b-button>
reflow() {
this.$refs.stacker.reflow()
}
which does work but adding it to mounted to do it automatically doesn't seem to do anything.
Is there any workaround or fix to remedy this situation?
So I tried adding a delay after the data has completed updating the variable for the stack in axios with the following:
setTimeout(() => { this.reflow() }, 800)
and it actually worked. However, I feel I shouldn't have to do this in order to get the initial page load to reflow correctly. Perhaps the stack component should detect full page load and then call a reflow and/or do what I did with the delay? Seems as if it's doing the reflow too soon.
I'll stick to this workaround for now until I get some input on this issue.
Thanks.
@bustarice thanks for the report. The Stack component should call reflow on the next tick after it's mounted. You can see this in the source code (src/Stack.vue). It seems that either the DOM isn't ready yet at that point, or the update/reflow methods don't get called correctly.
Could you check if this happens in any browser, and if the appropriate methods get called on page load? You should be able to debug this pretty easily by adding console.logs to the mounted, update and reflow methods of the Stack component.
Could you check if this happens in any browser, and if the appropriate methods get called on page load? You should be able to debug this pretty easily by adding
console.logs to themounted,updateandreflowmethods of theStackcomponent.
So I did as you suggested with the following console.log:
mounted() {
window.addEventListener('resize', this.reflow)
this.update()
console.log('mounted')
},
update() {
this.$nextTick(this.reflow)
console.log('updated')
},
reflow() {
this.updateColumnData()
let cols = this.getBaseColumns()
this.$emit('reflow', {
containerWidth: this.containerWidth,
columnCount: this.columnCount,
columnWidth: this.columnWidth,
})
this.$children.forEach((child, i) => {
child.$el.style.width = this.columnWidth + 'px'
let n = 0
if (i < this.columnCount)
n = i
else
{
let minH = -1
cols.forEach((col, j) => {
if ((minH == -1) || (col.h < minH))
{
n = j
minH = col.h
}
})
}
child.$el.style.transform = 'translate(' + cols[n].x + 'px, ' + cols[n].h + 'px)'
cols[n].h += child.$el.offsetHeight + this.gutterHeight
})
let containerHeight = 0
cols.forEach(col => containerHeight = Math.max(containerHeight, col.h))
this.$el.style.height = containerHeight + 'px'
console.log('reflowed')
}
console
updated Stack.vue?d914:76
mounted Stack.vue?d914:40
reflowed Stack.vue?d914:114
reflowed Stack.vue?d914:114
home.vue
<template>
<b-container id="home-page" fluid>
<stack
:column-min-width="250"
:gutter-width="1"
:gutter-height="1"
monitor-images-loaded
ref="stacker"
v-if="images.length"
>
<stack-item
v-for="(image, i) in images"
:key="i"
style="transition: transform 300ms"
>
<div class="content">
<div class="content-overlay"></div>
<b-img-lazy class="grid-image content-image" :src="image.image" :alt="image.alt_description"></b-img-lazy>
<div class="content-details fadeIn-bottom">
<b-link :to="image.link">
<h5 class="content-title">{{ image.title }}</h5>
<p class="content-text">{{ image.alt_description }}</p>
</b-link>
</div>
</div>
</stack-item>
</stack>
<!-- <span v-else>no results found</span> -->
</b-container>
</template>
<script>
import { Stack, StackItem } from 'vue-stack-grid'
export default {
components: {
Stack,
StackItem
},
data () {
return {
currentPath: '',
images: []
}
},
methods: {
getActiveListings() {
let routePath = this.currentPath
let url = 'listings/gethomelistings'
axios.post(url, {
path: routePath
})
.then((res) => {
this.images = res.data.listings
// temp workaround due to initial page load doesn't reflow correctly
// setTimeout(() => {
// if (res.data.listings.length) {
// this.reflow()
// }
// }, 800)
}, () => {
this.has_error = true
})
},
reflow() {
this.$refs.stacker.reflow()
}
},
created() {
this.getActiveListings()
},
mounted() {
this.currentPath = this.$route.path
},
watch: {
'$route.path': {
handler: function(route) {
this.currentPath = route
},
deep: true,
immediate: true
},
currentPath: function() {
this.getActiveListings()
}
}
}
</script>
<style lang="scss">
#home-page {
a {
cursor: pointer;
}
padding-left: 0px;
padding-right: 0px;
.content {
position: relative;
// width: 90%;
// max-width: 400px;
margin: auto;
overflow: hidden;
.content-overlay {
background: rgba(0,0,0,0.7);
position: absolute;
// height: 99%;
height: 100%;
width: 100%;
left: 0;
top: 0;
bottom: 0;
right: 0;
opacity: 0;
-webkit-transition: all 0.4s ease-in-out 0s;
-moz-transition: all 0.4s ease-in-out 0s;
transition: all 0.4s ease-in-out 0s;
img .grid-image {
width: 100%;
height: auto;
}
}
}
.content:hover .content-overlay {
opacity: 1;
}
.content-image {
width: 100%;
}
.content-details {
position: absolute;
text-align: center;
padding-left: 1em;
padding-right: 1em;
width: 100%;
top: 50%;
left: 50%;
opacity: 0;
-webkit-transform: translate(-50%, -50%);
-moz-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
-webkit-transition: all 0.3s ease-in-out 0s;
-moz-transition: all 0.3s ease-in-out 0s;
transition: all 0.3s ease-in-out 0s;
h5 {
color: #fff;
font-weight: 500;
letter-spacing: 0.15em;
margin-bottom: 0.5em;
text-transform: uppercase;
}
p {
color: #fff;
font-size: 0.8em;
}
}
.content:hover .content-details {
top: 50%;
left: 50%;
opacity: 1;
}
.fadeIn-bottom {
top: 80%;
}
.fadeIn-top {
top: 20%;
}
.fadeIn-left {
left: 20%;
}
.fadeIn-right {
left: 80%;
}
}
</style>
So it seems everything gets called correctly on the Stack component.
By removing my delay code, I tried on IE/Edge/Firefox/Chrome and all exhibit the same behavior.