Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

311
Vistas
Vue Router not scolling to correct hash location

When clicking a link on the app, the Router does not scroll to the correct hash location given. But it DOES scoll. The scroll is always about 1 element too high on the page. For example, if my page is this:

<template>
    <div id="div1">Div1</div>
    <div id="div2">Div2</div>
    <div id="div3">Div3</div>
    <div id="div4">Div4</div>
</template>

Then if I click a link that goes to hash "div3" it will scroll me so the top of div2. Only a very few select elements are scrolled to correctly. Is there a reason for this? Setting page margins?

Router code:

const router = new VueRouter({
  routes,
  mode: 'history',
  base: "/",
  scrollBehavior (to, from, savedPosition) {
    if (to.hash) {
        return {
          selector: to.hash,
          behavior: 'smooth',
        }
    } else {
        return { x: 0, y: 0 }
    }
  }
})

Example of code that calls the hash routing:

if (item.title == "Mission") {
    router.push({name: 'Explore', hash: '#mission-statement'});
} else if (item.title == "Our Story") {
    router.push({name: 'Explore', hash: '#our-story-container'});
} else if (item.title == "Shared principles") {
    router.push({name: 'Explore', hash: '#shared-principles-container'});
} else if (item.title == "Volunteer Opportunities") {
    router.push({name: 'Explore', hash: '#volunteer-container'});
} else if (item.title == "Gallery") {
    router.push({name: 'Explore', hash: '#galleries'});
} else if (item.title == "Living") {
    router.push({name: 'Explore', hash: '#living-container'});
} else if (item.title == "Contact Us") {
    router.push({name: 'Explore', hash: '#contact-us-container'});
} else {
    router.push("/explore")
}

SOLUTION:

With the help of IVO GELOV's answer I was able to update the scroll behavior function with the code below and all works as expected.

scrollBehavior (to, from, savedPosition) {
    let position = {}
    if (to.hash) {
        position = {
          selector: to.hash,
          offset: { x: 0, y: 100 },
          behavior: 'smooth',
        }
    } else {
        position = { x: 0, y: 0 }
    }
    return new Promise((resolve) => {
      setTimeout(() => {
        resolve(position)
      }, 100)
    })
  }
about 4 years ago · Juan Pablo Isaza
1 Respuestas
Responde la pregunta

0

Nuxt.js is using the following code in its ./nuxt/router.js - perhaps you can adopt it to your usecase:

import Vue from 'vue'
import Router from 'vue-router'

Vue.use(Router) 

if (process.client) {
  window.history.scrollRestoration = 'manual'
}
const scrollBehavior = function (to, from, savedPosition) {
  // if the returned position is falsy or an empty object,
  // will retain current scroll position.
  let position = false

  // if no children detected
  if (to.matched.length < 2) {
    // scroll to the top of the page
    position = { x: 0, y: 0 }
  } else if (to.matched.some((r) => r.components.default.options.scrollToTop)) {
    // if one of the children has scrollToTop option set to true
    position = { x: 0, y: 0 }
  }

  // savedPosition is only available for popstate navigations (back button)
  if (savedPosition) {
    position = savedPosition
  }

  return new Promise(resolve => {
    // wait for the out transition to complete (if necessary)
    window.$nuxt.$once('triggerScroll', () => {
      // coords will be used if no selector is provided,
      // or if the selector didn't match any element.
      if (to.hash) {
        let hash = to.hash
        // CSS.escape() is not supported with IE and Edge.
        if (typeof window.CSS !== 'undefined' && typeof window.CSS.escape !== 'undefined') {
          hash = '#' + window.CSS.escape(hash.substr(1))
        }
        try {
          if (document.querySelector(hash)) {
            // scroll to anchor by returning the selector
            position = { selector: hash }
          }
        } catch (e) {
          console.warn('Failed to save scroll position. Please add CSS.escape() polyfill (https://github.com/mathiasbynens/CSS.escape).')
        }
      }
      resolve(position)
    })
  })
}

export function createRouter () {
  return new Router({
    mode: 'history',
    base: '/',
    linkActiveClass: 'nuxt-link-active',
    linkExactActiveClass: 'nuxt-link-exact-active',
    scrollBehavior,
    routes: [ .... ],
    fallback: false
  })
}

An example implementation (taken from https://dev.to/dimer191996/nuxt-js-smooth-scrolling-with-hash-links-94a) - you may also need to set window.history.scrollRestoration = 'manual' if your <router-view> is wrapped inside a <transition>:

scrollBehavior: async (to, from, savedPosition) => {
      if (savedPosition) {
        return savedPosition
      }

      const findEl = async (hash, x) => {
        return document.querySelector(hash) ||
          new Promise((resolve, reject) => {
            if (x > 50) {
              return resolve()
            }
            setTimeout(() => { resolve(findEl(hash, ++x || 1)) }, 100)
          })
      }

      if (to.hash) {
        let el = await findEl(to.hash)
        if ('scrollBehavior' in document.documentElement.style) {
          return window.scrollTo({ top: el.offsetTop, behavior: 'smooth' })
        } else {
          return window.scrollTo(0, el.offsetTop)
        }
      }

      return { x: 0, y: 0 }
    }
about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda