What is the best method to determine the current scroll position using JavaScript?

Presently, I am focusing on implementing scroll to top button functionality.

The button appears when the content is scrolled to the bottom. My goal is to store the last position when the scroll to top button is clicked so that the user can return to that position when clicking the scroll to bottom button.

Do you have any suggestions for a more effective way to retrieve the current scroll position?

ScrollToTopBottom.vue

<template>

    <div v-if="showScroll" v-scroll="onScroll">
      <v-btn v-if = "!isVisible"
          fab fixed bottom right color="primary" @click="toBottom">
          <v-icon>mdi-arrow-down-bold-box-outline</v-icon>
      </v-btn>

      <v-btn v-else
          fab fixed bottom right color="primary" @click="toTop">
          <v-icon>mdi-arrow-up-bold-box-outline</v-icon>
      </v-btn>
    </div>
</template>

<script>

export default{
    data () {
        return {
        isVisible: false,
        position: 0,
        hasVScroll: false,
    }
  },
   methods: {
    onScroll () {
      this.isVisible = window.scrollY > 500
    },
    toTop () {
      this.position = window.scrollY
      window.scrollTo({
        top: 0,
        left: 0,
        behavior: 'smooth'
      })
    },
    toBottom(){
      let pos = this.position > 0 ? this.position : document.body.scrollHeight
      window.scrollTo({
        top: pos,
        behavior: 'smooth'
      })
    },
    showScroll(){
      this.hasVScroll = document.body.scrollHeight > document.body.clientHeight;
    }
  }
}

</script>

</script>

Answer №1

When you click the button at the top, your current position will be saved. You can then check it by clicking the button at the bottom:

Vue.component('scrollToTopButton', {
  template: `
    <div v-scroll="onScroll" v-if="hasVerticalScroll">
      <v-btn v-if="!isVisible" fab fixed bottom right color="primary" @click="toBottom">
        <v-icon>mdi-arrow-down-bold-box-outline</v-icon>
      </v-btn>
      <v-btn v-else fab fixed bottom right color="primary" @click="toTop">
        <v-icon>mdi-arrow-up-bold-box-outline</v-icon>
      </v-btn>
    </div>
  `,
  data () {
    return {
      isVisible: false,
      position: 0
    }
  },
   methods: {
    onScroll() {
      this.isVisible = window.scrollY > 50
    },
    toTop() {
      this.position = window.scrollY
      window.scrollTo({
        top: 0,
        left: 0,
        behavior: 'smooth'
      })
    },
    toBottom(){
      let pos = this.position > 0 ? this.position : document.body.scrollHeight
      window.scrollTo({
        top: pos,
        behavior: 'smooth'
      })
    },
  },
  computed: {
    hasVerticalScroll(){
      return document.body.offsetHeight > window.innerHeight;
    }
  }
})
new Vue({
  el: "#demo",
  vuetify: new Vuetify(),
  
})
<link href="https://cdn.jsdelivr.net/npm/@mdi/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="3e5851504a7e081046">[email protected]</a>/css/materialdesignicons.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="17616272637e716e5725396f">[email protected]</a>/dist/vuetify.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="6d1b18082d5f4315">[email protected]</a>/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="bacccfdfced3dcc3fa8894c2">[email protected]</a>/dist/vuetify.js"></script>
<div id="demo" >
  <v-app>
    <v-main>
      <v-container>
        <div>xxx</div><div>xxx</div><div>xxx</div><div>xxx</div><div>xxx</div><div>xxx</div><div>xxx</div><div>xxx</div><div>xxx</div><div>xxx</div><div>xxx</div><div>xxx</div><div>xxx</div><div>xxx</div><div>xxx</div><div>a</div><div>xxx</div><div>xxx</div><div>xxx</div><div>xxx</div><div>xxx</div><div>xxx</div><div>xxx</div><div>xxx</div><div>xxx</div><div>xxx</div><div>xxx</div><div>xxx</div><div>xxx</div><div>xxx</div><div>xxx</div><div>xxx</div><div>xxx</div>
        <scroll-to-top-button />
      </v-container>
    </v-main>
  </v-app>
</div>

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

Can anyone explain why I keep encountering an endless loop when using react hooks?

Having a bit of trouble with fetching data from a JS file that is mimicking an API with some endpoint methods. When I console log the data, everything seems fine, but for some reason, I keep running into an infinite loop when using hooks. I've tried t ...

VueX getter not functioning with Async/Await, while log function does work

I am working on a situation where I have a collection of conversations associated with userIDs that I need to iterate through. Within this loop, I must make a call to Firebase to retrieve the corresponding userNames and then generate an object containing t ...

Decoding JavaScript elements embedded in an HTML website

My current HTML site includes the following code: <script type="text/javascript"> jwplayer('player_container').setup( { 'width': '640', ...

How can I transform this imperative reducer into a more declarative format using Ramda?

I am currently working with a reducer function that aggregates values in a specific way. The first argument is the aggregated value, while the second argument represents the next value. This function reduces over the same reaction argument, aggregating th ...

The never-ending cycle and memory overload that occur when using Angular's ngRoute

It seems like I may have hit a roadblock while attempting to get ng-view and ngRoute up and running. Everything appeared to be functioning correctly, but it looks like the entire process is caught in a loop. Just to provide some context, I am working with ...

How to style large numbers with AngularJS

I'm facing a challenge with large numbers in a table and I'm seeking a solution to format them, ideally as $13b, $10m... Has anyone encountered this issue before and discovered a customized filter or solution for it? Appreciate any help! ...

Dynamic Content Sorting with JavaScript and jQuery

I am presenting various courses that are available, and I am utilizing JavaScript/jQuery to display or hide them based on element classes. You can view the page here. Currently, the script conceals all content on the page and then reveals items that matc ...

Vue.js - Identify dynamic input fields as they are generated and modify their color when the value changes

I've set up a dynamic table with editable fields using Vue.js. Here's how it looks: <b-table :items="filtered" :fields="columns"> <template v-for="field in editableFields" v-slot:[tableCell(field.key)]="{ item }"> &l ...

Modify the value of a variable every 250 milliseconds

Currently working on a game website and stuck at the registration stage. We are looking to allow players to input a code in their Ingame notes for verification purposes. I have created a PHP class to retrieve the ingame notes, but now I need to set a java ...

Tips for creating nested master-detail or master-detail-detail queries in Loopback

My set up includes category and category_subs in a master-detail model, with the post model being linked to category_subs. I have successfully retrieved the master-detail information for both categories, but now I am unsure of how to include the post and e ...

Switching class names on click in Vue.js

When clicked, I would like to toggle the class name from "product fav" to "product fav active". The change should be conditional; if the class is already active, it should be removed. ...

Are there any risks associated with using nested setTimeout functions with the same name?

While reviewing the source code of typed.js, I noticed that the main function in this plugin utilizes a design pattern with multiple setTimeout functions nested inside one another. Here is a snippet of the code: self.timeout = setTimeout(function() { / ...

contenteditable -- Utilizing AngularJS to create a block element for the title only

When I click on an input field that is editable, I want the background color to change to white within the box. Can someone please assist me with this? Below is my code: HTML <div id="section{{section.index}}"> <h2 class="title" contentedit ...

Explanation of Default Export in TypeScript

I recently started learning about JS, TS, and node.js. While exploring https://github.com/santiq/bulletproof-nodejs, I came across a section of code that is a bit confusing to me. I'm hoping someone can help explain a part of the code. In this project ...

Struggling to understand JSON in joint.js?

I am trying to utilize the joint.js library to render a JSON data as a chart... let paper = new joint.dia.Paper({ el: $('#paper'), width: 600, height: 200, model: graph }); let graph = new joint.dia.Graph; let json = '{"em ...

Modify background image upon hovering using AngularJS

I cannot seem to make the background images of my divs change. Despite trying various options, none of them have been successful. Here's an example of my code: <div ng-controller="mainController" class="main"> <div ng-repeat="land in lan ...

Typography Addition on Flexslider

I am currently working with flexslider and trying to incorporate a unique text overlay on each individual slide, but so far I have been unsuccessful. <div class="flexslider"> <ul class="slides"> <li> <img src ...

What is the method for accessing Vue.prototype in an external JS file?

"react": "^16.8.6" In main.js, I have defined properties as follows: Object.defineProperties(React.prototype, { apiURL: { value: process.env.API_ROOT, writable: false } }); Furthermore, there is another JavaScript file cal ...

Angular 5: There was an issue with the property not defined for lowercase conversion

I keep encountering this error whenever I attempt to filter a column of a table. The data is retrieved from a FireStore cloud collection and the 'auteur' field is defined in each document. Here is how my component looks: import { Component, OnI ...

When async is set to true in an Ajax call, the response may come

I recently developed a function that works perfectly fine when the async option is set to false. However, I am now looking to achieve the same functionality and return value but with async set to true. function Call(param, proc) { var url = "../../ ...