Trigger Vue to scroll an element into view once it becomes visible

I created a dynamic form that calculates 2 values and displays the result card only after all values are filled and submitted, utilizing the v-if directive.

Vuetify is my chosen UI framework for this project.

This is the approach I took:

<template>
  <v-container>
    <v-row class="mt-2" justify="center">
      <v-col cols="12" sm="8" md="6">
        <v-form ref="form" @submit.prevent="onSubmit">
          <v-row class="mb-1">
            <v-col cols="6">
        
              <v-select
                v-model="fighter1"
                :items="fighters"
                item-text="name"
                item-value="id"
                return-object
                label="Player 1"
                :rules="[(v) => !!v || 'Required.']"
              />
            </v-col>

            <v-col cols="6">
  
              <v-select
                v-model="fighter2"
                :items="fighters"
                item-text="name"
                item-value="id"
                return-object
                label="Player 2"
                :rules="[(v) => !!v || 'Required.']"
              />
            </v-col>
          </v-row>

          <!-- This is the submit button -->
          <ReadyToFight />
        </v-form>
      </v-col>
    </v-row>

    <v-row>
      <v-col>

        <!-- This is the result card -->
        <v-card v-if="result" id="result" class="pb-2">
          <h1 class="text-center text-uppercase result-score">{{ result }}</h1>
          <h2 class="text-center text-uppercase result-text">
            {{ resultText }}
          </h2>
        </v-card>
      </v-col>
    </v-row>
  </v-container>
</template>

<script lang="ts">
import { Fighter, fighters } from '@/data/fighters'
import matchupsChart from '@/data/matchups'
import Vue from 'vue'
import { MatchupTypes, toResult } from '~/data/matchupTypes'

type IndexPageType = {
  fighters: Fighter[]
  fighter1: Fighter | undefined
  fighter2: Fighter | undefined
  result: MatchupTypes | undefined
}

export default Vue.extend({
  name: 'IndexPage',
  data(): IndexPageType {
    return {
      fighters,
      fighter1: undefined,
      fighter2: undefined,
      result: undefined
    }
  },
  computed: {
    resultText(): string {
      if (this.result) return toResult(this.result)
      return `Can't get result`
    }
  },
  
  // Attempted to watch the result changing
  // to scroll into view when it happens
  watch: {
    result(newResult) {
      if (newResult) document.querySelector('#result')?.scrollIntoView()
    }
  },
  methods: {
    onSubmit() {
      ;(this.$refs.form as any).validate()
      if (this.fighter1 && this.fighter2) {
        this.result = matchupsChart
          .get(this.fighter1.id)
          ?.get(this.fighter2.id) as MatchupTypes
      }
    }
  }
})
</script>

The main idea behind my approach was:
Monitor the result, and if it becomes truthy, execute scrollIntoView()

Unfortunately, this approach did not work due to the result changing before the rendering of the element.

If anyone has suggestions on how to tackle this issue, please share your ideas!

Answer №1

The reason for this behavior is that the element with the ID #result has not been rendered in the DOM when the watcher is triggered. To ensure that the DOM has been updated before trying to scroll the element into view, you should use this.$nextTick() like so:

watch: {
    result(newResult) {
        if (newResult) {
            this.$nextTick().then(() => document.querySelector('#result')?.scrollIntoView());
        }
    }
},

If you are comfortable with async/await, you can achieve the same result using the following approach:

watch: {
    async result(newResult) {
        if (newResult) {
            await this.$nextTick();
            document.querySelector('#result')?.scrollIntoView();
        }
    }
},

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Requesting Axios.get for the value of years on end

I'm grappling with obtaining a JSON file from the server. The endpoint requires a year parameter, which needs to be set as the current year number as its value (e.g., ?year=2019). Furthermore, I need to fetch data for the previous and upcoming years a ...

Iterating through div elements and assigning unique ids to them before enabling click functionality

I'm attempting to create multiple div elements inside my loop that will each display a unique message when clicked. However, I'm encountering issues with the code and can't seem to make it work as intended. Here is what I am trying to achiev ...

Submitting an extremely large string to an Express server using JS

How can a large String be efficiently sent to a Node.js Express server? On my webpage, I am using Codemirror to load files from an Express server into the editor. However, what is the most effective method for sending "the file" (which is actually a bi ...

What advantages does event delegation in JavaScript offer compared to using jQuery's event handling?

Vanilla JavaScript: parentNode.addEventListener("click", function(event) { if (event.target === childNode) { code here } }); versus jQuery: $(parentNode).on("click", childNode, function() {}); ...

The module 'PublicModule' was declared unexpectedly within the 'AppModule' in the Angular 4 component structure

My goal is to create a simple structure: app --_layout --public-footer ----public-footer.html/ts/css files --public-header ----public-header.html/ts/css files --public-layout ----public-layout.html/ts/css files In public-layout.html, the stru ...

PHP unable to display HTML form element using its designated ID attribute

I've been experiencing some difficulties with PHP echoing a label element that contains an ID attribute within an HTML form. My intention was to utilize the ID attribute in order to avoid having to modify the JS code to use the name attribute instead. ...

There appears to be an issue with the functionality of the Bootstrap toggle tab

Currently, I am facing a toggle issue and having trouble pinpointing the root cause as there are no errors appearing in the console. The problem involves two tabs that can be toggled between - "pay" and "method". Initially, the default tab displayed is "pa ...

Using Axios.put will only modify specific fields, not all of them

Recently, I came across a tutorial that utilized nodejs, mysql2, express, and vuejs. The tutorial can be found at: For my project, I decided to use my custom database and tables instead. However, I encountered an issue when sending an axios.put request - ...

Javascript callback function

Greetings everyone! I've developed a simple nodesjs server using express. The server includes a login page where users enter their credentials to be checked against an Sqlite3 DB. My concern lies in the fact that the callback function only executes on ...

In Visual Studio 2022, curly braces are now positioned on the same line for JavaScript code

I'm struggling with keeping Visual Studio from moving my curly braces to a new line whenever I auto format the code. Here's an example: Let's say I write this code: $('#details-modal').on('change', '#Foo1', fun ...

Accessing a variable from one function within another function in Vue

How can I access and utilize the ctx variable from the initGrid() function in the drawGrid() function? Despite trying to use "this," it seems that the variable cannot be accessed within the drawGrid() function. <script> export default { data: ( ...

Encountering an Unhandled Exception with Laravel Sanctum and Vuex when Implementing Vue Router Navigation Guard

Looking for some advice on my current situation. I have a Laravel application with a Vue front-end, and I am using Laravel Sanctum to connect to the API within the same app. My goal is to configure authentication guards so that routes can only be accessed ...

Troubleshooting error messages in the console during conversion of image URL to Base64 in AngularJS

While attempting to convert an image URL to Base64 using the FromImageUrl method, I encountered an error in my console. Access to the image located at '' from the origin 'http://localhost:8383' has been blocked due to CORS policy ...

Issue encountered with mouse handling on SVG elements that overlap is not functioning as anticipated

I am working with multiple SVG path elements, each contained within a parent SVG element, structured like this: <svg class="connector" style="position:absolute;left:277.5px;top:65px" position="absolute" pointer-events:"none" version="1.1" xmlns="http:/ ...

Is it possible for me to deactivate the Material-UI SpeedDial hover function?

I need to override the default mouseover/hover behavior of Material-UI's SpeedDial component (https://material-ui.com/api/speed-dial/). Currently, when hovering over the primary icon, the SpeedDial opens. It also opens on click, causing confusion for ...

The Bootstrap alert refuses to close when the close button is clicked

I'm attempting to utilize a Bootstrap alert for displaying a warning. The alert automatically fades and dismisses after a period of time, but I want to provide the user with the option to manually close it. I've included jQuery and js/bootstrap.m ...

Add objects to a web address that leads nowhere but can still be linked to

It has come to my realization that the vagueness of my question might be obstructing my search efforts online. Here is the scenario: I am aiming to create a URL structure like this: http://app.myurl.com/8hhse92 The identifier "8hhse92" does not correspo ...

Utilizing Vue JS to set an active state in conjunction with a for loop

Currently in Vue, I have a collection of strings that I am displaying using the v-for directive within a "list-group" component from Bootstrap. My goal is to apply an "active" state when an item is clicked, but I am struggling to identify a specific item w ...

The npm start command is no longer functioning in Angular 5

When attempting to start angular 5 with npm, I encountered an error that reads: TypeError: callbacks[i] is not a function Can anyone shed some light on where this error might be coming from? It seemed to pop up out of the blue and I can't seem to ...

Updating from Babel 6 to Babel 7 resulted in an error: Unexpected token detected (spread operator)

I recently made the transition from Babel 6 to Babel 7 but encountered some errors that I am struggling to resolve. During the migration, I came across an issue where I received the following error even though I was using @babel/plugin-proposal-object-res ...