Guide to seamlessly navigating to an element using a hash in NuxtJS

My aim is to create a smooth scrolling anchor link menu using Nuxt.js, where the user can click on a link and be directed to the corresponding page section. However, I'm facing a dilemma as there are multiple approaches to achieve this functionality, and I'm unsure which one is the most suitable.

Option 1:

In my first attempt, I implemented a menu that calculates the offsetTop of each section div to determine the scroll distance when a user clicks on a menu link. The issue with this method is that certain values of the divs, such as offsetHeight and offsetTop, tend to change when the project is deployed to the server. Consequently, the links end up scrolling to incorrect positions and do not function correctly.

I experimented with swapping the order of the 'Value' and 'Problem' sections, which temporarily resolved the problem. However, the correct sequence of sections needed to be maintained.

In this approach, I utilize the created() lifecycle hook to retrieve these values and store them in Vuex state. These values are then accessed in another component where the menu functionality resides:

.................................... (The rest of the original content remains unchanged) ..........................

Now, I find myself torn between these two options, unsure of where to invest my time and effort for the best outcome.

Answer №1

Your operations here are quite complex and may vary across different browsers. I suggest sticking with a Vue approach instead of vanilla JS for better compatibility.

I was able to implement a local scroll functionality following my previous answer and by adding the code in /pages/index.vue

<template>
  <div>
    <button
      v-scroll-to="{ el: '#scroll-here', duration: 300 }"
      @click="$router.push({ name: 'index', hash: '#scroll-here' })"
    >
      Let's scroll !!
    </button>
    <nuxt-link to="/about">go to about page</nuxt-link>

    <p class="big-block">
      (Content)
    </p>

    <p id="scroll-here">scroll smooth to here please</p>

    <p class="big-block">
      (More content)
    </p>
  </div>
</template>

<script>
export default {
  name: 'Index',
}
</script>

<style>
.big-block {
  min-height: 100vh;
}
</style>

We utilize vue-scrollto package to target our ID, all available options can be found here.

If you want a global behavior, check out my answer here with the code in /app/router.scrollBehavior.js

import Vue from 'vue'
import VueScrollTo from 'vue-scrollto'
Vue.use(VueScrollTo)

export default function (to, from, savedPosition) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      if (to.hash === '#scroll-here') {
        VueScrollTo.scrollTo('#scroll-here', 300, { easing: 'linear' })
      }
    }, 10)
  })
}

You can choose between a local solution per button or a more widespread global one based on your requirements.


You can view a demo of both local and global scrolling solutions here (reduce browser viewport size for best experience).
The related repository is hosted on GitHub here.

Answer №2

Defining what is considered "correct" in development can be a challenging task. In my opinion, the concept of "correct" revolves around functionality...

When deciding on which path to take, it's important to consider whether Vue.js tools are advanced enough for your specific needs. If they are primarily designed for simplifying complex processes, this might be causing issues with option 2. In such cases, it may be more effective to utilize CSS and vanilla JS to craft a refined solution rather than trying to force fit framework tools. Based on your description, it appears that solution 1, utilizing mostly vanilla JS, is performing better than solution 2. Remember, JavaScript is a fundamental skill possessed by all web developers. Therefore, if a problem can be elegantly solved using vanilla JS instead of within a particular framework like Vue, it may be wise to opt for the former.

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

Difficulty encountered while deploying a React application on Netlify

I followed the instructions on a Medium link to deploy my React application on Netlify: To set up the production mode, I utilized an express server for defining build scripts. After creating the build scripts on my local machine, I uploaded them to the Ne ...

Splitting Code in React Components using Webpack within a Ruby on Rails Application

I'm currently integrating ReactJS components into my Rails application using the Webpack gem. However, I am facing an issue where the React components are only being loaded in specific areas within the layout of the Rails application. This results in ...

Adding to object in an external JSON file using javascript

I am working with an external file called file.json which contains the following values: { "number": "value" } My goal is to run a function that will append new data to the existing file instead of overwriting it. For instance, after running the func ...

Retrieving data from MySQL through AJAX does not yield any information

I have been following a tutorial from W3 schools on PHP and AJAX database. Majority of the content is working fine, however it seems that there is no data being retrieved from the MySQL database I created called "exercises" in the "exercisedb" database. B ...

I'm experiencing issues with my code involving HTML, CSS, and jQuery

Recently, I started learning about jQuery and came across a tutorial on creating a sticky nav bar. However, something went wrong during the implementation and now I don't know how to fix it! In my Script file, I have written code that should run on l ...

Is there a more efficient method for implementing server side rendering in a Next.js application?

Currently, I am implementing server-side rendering in my Next.js application. This specific component is responsible for returning HTML content. I'm wondering if there are more efficient methods available? import Feature from 'components/home/Fea ...

What's the best way to mount multiple Vue Single File Components?

Suppose you have an index.js file structured like this: new Vue({ el: '#app', components: { 'hello': Hello, 'counter': Counter, 'goodbye': GoodBye } }); And your index.html file ...

Prevent ESLint from linting files with non-standard extensions

My .estintrc.yaml: parser: "@typescript-eslint/parser" parserOptions: sourceType: module project: tsconfig.json tsconfigRootDir: ./ env: es6: true browser: true node: true mocha: true plugins: - "@typescript-eslint" D ...

"Encountered a problem when trying to access file with node

An error has occurred: module.js:471 throw err; ^ Error: Module not found at '/Users/vinclo/app.js' at Function.Module._resolveFilename (module.js:469:15) at Function.Module._load (module.js:417:25) at Module.runMain (module.js:604:10) at run ( ...

Skipping validation while navigating back on SmartWizardIf you need to bypass validation during backward

Looking for assistance with Jquery smartwizard? Check out the link. I want to disable validation when a user clicks on the "Previous" button in any step, except for the first step where the Previous button is disabled by default. Below is my JavaScript co ...

Ensuring that a service is completely initialized before Angular injects it into the system

When Angular starts, my service fetches documents and stores them in a Map<string, Document>. I use the HttpClient to retrieve these documents. Is there a way to postpone the creation of the service until all the documents have been fetched? In ot ...

Create custom AngularJS directives for validation and store them in a variable

Through the use of AngularJS, I've developed a directive called "integer" that invalidates a form if anything other than integers are entered. Because I'm generating the page dynamically by fetching data from the database, it would be helpful to ...

Are 'const' and 'let' interchangeable in Typescript?

Exploring AngularJS 2 and Typescript led me to create something using these technologies as a way to grasp the basics of Typescript. Through various sources, I delved into modules, Typescript concepts, with one particularly interesting topic discussing the ...

Solving required packages in Express server

I am encountering difficulties with resolving dependencies on my express server. Below is the structure of my project: Calculator --dist ----app -------calculator.js -------server.js --node_modules --src ----app --------calculator.js --------server.js -- ...

I possess a JSON object retrieved from Drafter, and my sole interest lies in extracting the schema from it

Working with node to utilize drafter for generating a json schema for an application brings about too much unnecessary output from drafter. The generated json is extensive, but I only require a small portion of it. Here is the full output: { "element": ...

What could be the reason for scope.$watch failing to function properly?

My AngularJS directive has a template with two tags - an input and an empty list. I am trying to watch the input value of the first input tag. However, the $watch() method only gets called once during initialization of the directive and any subsequent chan ...

There seems to be an issue with the useReducer value not updating when logging it in a handleSubmit function

I'm currently incorporating useReducer into my Login and Register form. Interestingly, when I attempt to log the reducer value, it only displays the default value. However, if I log it within the useEffect hook, it functions correctly. Below is a sn ...

Troubleshooting resizing images in React using Material UI's useStyles

When attempting to resize an image using React, I am encountering a problem where adjusting the height and width of the tag with useStyles does not reduce the size of the image but instead moves it around on the page. Here is the code snippet: import { ma ...

Packing third-party npm modules with Webpack for seamless integration

Description I am currently working on a project that involves nodejs, TypeScript, and express. The source files with a *.ts extension are being bundled using webpack, while the node_modules folder is excluded using webpack-node-externals. However, when I ...

Learn the process of dynamically updating the source of an HTML5 video

Currently, I am working on a project that involves dynamically loading multiple videos onto a webpage. The structure of my HTML is quite straightforward - it consists of a single video tag. <video controls preload width="520" height="350" id="video"> ...