Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Horizontal scrollbar is visible on page refresh #8

Open
bustarice opened this issue Dec 25, 2019 · 3 comments
Open

Horizontal scrollbar is visible on page refresh #8

bustarice opened this issue Dec 25, 2019 · 3 comments

Comments

@bustarice
Copy link

bustarice commented Dec 25, 2019

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?

@bustarice
Copy link
Author

bustarice commented Dec 26, 2019

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.

@WouterFlorijn
Copy link
Owner

@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.

@bustarice
Copy link
Author

bustarice commented Jan 1, 2020

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.

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants