1

In my Vue 3 project, I have this button in a component:

<template>
  <button type="button" class="btn btn-success" :data-id="product.id"
    v-on:click="hideButtonAndScroll(product.id)">Get Offer</button>

  <!-- ... some code here ... -->

  <offer-form :product="product"></offer-form>
</template>

<script>
export default {
  props: ['products'],
  data() {
    return { visibleFormId: 0 };
  },
  methods: {
    hideButtonAndScroll(id) {
      this.visibleFormId = id;
      window.scrollTo({
        top: document.getElementById('product-id-' + id).offsetTop,
        left: 0,
        behavior: 'smooth',
      });
    }
  },
}
</script>

In the OfferForm.vue file, I have this HTML code:

<template>
  <div :id="'product-id-' + product.id">
    <!-- ... -->
  </div>
</template>

The problem is when I call the document.getElementById('product-id-' + id) function, actually the element doesn't exist yet.

Is there any way to wait until the rendering has finished? and then start scrolling?

1
  • 1
    Emit events from OfferForm.vue when data has been loaded and listen to it on parent vue upon which scrolling will be performed. Commented Feb 15, 2021 at 16:35

1 Answer 1

3

You can wait until the next render cycle with await this.$nextTick() to see any side effects from changing visibleFormId (using async/await below):

export default {
  methods: {
  👉async hideButtonAndScroll(id) {
      this.visibleFormId = id;

    👉await this.$nextTick();

      window.scrollTo({
        top: document.getElementById('product-id-' + id).offsetTop,
        left: 0,
        behavior: "smooth",
      });
    },
  },
}

demo

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.