Vue bug: offsetTop consistently outputs 0

When attempting to fix an element when the user scrolls past it, I encountered an issue. Despite the element (in this case a navbar) being approximately 300px in height, it consistently returns a value of 0.

Within my mounted method where the calculation is performed, the value of stickyTop is always logged as 0.

Both the usage of offsetTop and getBoundingClientRect().top result in a constant output of 0.

mounted() {
    let self = this;
    let sticky = document.getElementById("sticky");
    let stickyTop = sticky.offsetTop;
    let scrolled = false;
    let $window = window;

    window.addEventListener("scroll", function (e) {
      scrolled = true;
    });

    let timeout = setInterval(function () {
      /* If the page was scrolled, handle the scroll */
      if (scrolled) {
        scrolled = false;
        if (window.pageYOffset > stickyTop) {
          self.isScrolled = true;
        } else {
          self.isScrolled = false;
        }
      }
    }, 2000);
  },

For reference, here is the entire component:

<template>
  <nav
    id="sticky"
    class="LAYOUTnav1_maincontainer"
    :class="{ fixed_class: isScrolled }"
    @mouseleave="activeNav = null"
  >
    <div class="LAYOUTnav1_links_container">
      <a
        class="LAYOUTnav1_link_container hover_slide_center"
        v-for="(link, index) in visibleLinks"
        :key="index"
        @mouseover="selectNav(link, $event)"
        @click="selectNav(link, $event)"
        :href="link.url"
        :class="{ active_nav: meta.activeNav == link.name }"
      >
        <span class="LAYOUTnav1_link_text">{{ link.name }}</span>
      </a>
      <button
        class="LAYOUTnav1_cart_button"
        type="button"
        @click="TOGGLE_CART_TAB()"
        v-bg-color="'rgb(10,10,10)'"
      >
        <i class="LAYOUTnav1_cart_button_icon fas fa-shopping-cart"></i>
        <span
          class="LAYOUTnav1_cart_button_text"
          v-if="cartItems.length != 0"
          >{{ cartItems.length }}</span
        >
        <span class="LAYOUTnav1_cart_button_text" v-if="cartItems.length == 0"
          >¡El carrito esta vacio!</span
        >
      </button>
    </div>
    <div class="LAYOUTnav1_responsive_container">
      <a class="LAYOUTnav1_responsive_title" href="/">{{
        globals.generals.appName
      }}</a>
      <button
        class="LAYOUTnav1_responsive_button"
        @click.self="selectNav({ name: 'responsive', sublinks: [] }, $event)"
      >
        <i
          class="LAYOUTnav1_responsive_button_icon fas fa-bars"
          v-show="!showResponsiveNav"
        ></i>
        <i
          class="LAYOUTnav1_responsive_button_icon fas fa-times"
          v-show="showResponsiveNav"
        ></i>
      </button>
    </div>
    <div
      class="LAYOUTnav1_dropdowns_container"
      v-show="activeNav == 'responsive'"
    >
      <a
        class="LAYOUTnav1_dropdown_container"
        v-for="link in visibleLinks"
        :key="link.name"
        @mouseover="selectNav(link, $event)"
        @click="selectNav(link, $event)"
        :href="link.url"
        :class="{ active_nav: meta.activeNav == link.name }"
      >
        <span class="LAYOUTnav1_dropdown_text">{{ link.name }}</span>
      </a>
    </div>
  </nav>
</template>
<!--SCRIPTS-->
<script>
import $ from "jquery";
import { mapState, mapGetters, mapActions, mapMutations } from "vuex";
export default {
  name: "LAYOUTnav6",

  computed: {
    ...mapState("Cart", ["cartItems"]),

    withLinks: function () {
      return this.globals.navLinks.filter(
        (link) => link.sublinks.length > 0 && link.subLinks
      );
    },

    visibleLinks: function () {
      return this.globals.navLinks.filter(
        (link) =>
          (link.isVisible && !link.hasSublinks) ||
          (link.isVisible && link.hasSublinks && link.sublinks.length > 0)
      );
    },
  },

  data: function () {
    return {
      activeNav: null,
      showResponsiveNav: false,
      isScrolled: false,
    };
  },

  props: {
    globals: { required: true },
    meta: { required: true },
  },

  mounted() {
    console.log(this.$options.name + " component successfully mounted");
    let self = this;
    let sticky = document.getElementById("sticky");
    //sticky.style.border = '10px solid red';
    //let stickyTop = sticky.getBoundingClientRect().top;
    let stickyTop = sticky.offsetTop;
    console.log(stickyTop);
    let scrolled = false;
    let $window = window;

    window.addEventListener("scroll", function (e) {
      scrolled = true;
    });

    let timeout = setInterval(function () {
      /* If the page was scrolled, handle the scroll */
      if (scrolled) {
        scrolled = false;
        if (window.pageYOffset > stickyTop) {
          self.isScrolled = true;
        } else {
          self.isScrolled = false;
        }
      }
    }, 2000);
  },

  methods: {
    ...mapMutations("Cart", ["TOGGLE_CART_TAB"]),

    selectNav: function (link, event) {
      if (link.sublinks.length > 0) {
        //event.preventDefault();
        this.activeNav = link.name;
      } else {
        this.activeNav = link.name;
        this.showResponsiveNav = !this.showResponsiveNav;
      }
    },
  },
};
</script>

Answer №1

It is probable that there is another element (such as a child of window, body, etc) having the overflow property set to auto or scroll. This is the particular element you should retrieve offsetTop from.

Employing development tools can assist in pinpointing the element that

is in possession of the scroll bar
. After identification, make sure to reference that element instead of using window.

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

Customizing jQuery validation parameters (require identical functionality)

Utilizing jquery validation and bootstrap, I have encountered an issue when dealing with multiple forms in a view. The styling of validation messages does not remain consistent when I have to create a validator object manually for each form. How can I ens ...

Developing a way to make vue-custom-element compatible for embedding in external websites

I've been exploring ways to use a component from my Vue website on another site by embedding it in HTML. I came across https://github.com/karol-f/vue-custom-element and found this helpful guide. After installing the npm packages vue-custom-element an ...

Binding data to custom components in Angular allows for a more flexible

In my current scenario, I am looking to pass a portion of a complex object to an Angular component. <app-component [set]="data.set"></app-component> I want the 'data.set' object in the parent class to always mirror the 'set&apo ...

Automatically add values after successful Facebook login

Currently, I am working on a Cordova project where I have implemented Facebook login for user authentication. While the login is functioning correctly, I am facing an issue where I need to manually press a button with the ID getinfo in order for the values ...

Utilize a Javascript function to retrieve a string and set it as the ID

I'm trying to modify a div ID by appending either a 'W' or 'H' depending on whether the screen width is greater than the height. I figured I could achieve this using JavaScript since PHP lacks the ability to detect screen sizes. A ...

Could the act of one function updating state and another immediately accessing it lead to a potential race condition occurring?

I am faced with a scenario where I have two components - one for uploading files and the other for submitting a form. Each component has its own callback function that needs to trigger a backend request once completed. My objective is to ensure that the ba ...

What is the significance of the "rc" within the version structure of an npm package?

Can someone help me understand what the rc in 2.2.0-rc.0 signifies? I'm curious if it indicates that this version is ready for production use. ...

Having trouble updating the dropdown value in a React child component

There are two main components in my code: App component: class App extends Component { constructor(props) { super(props); this.state = { selectedScale: "WholeTone" }; this.handleScaleSelect = this.handleScaleSelect.bind(this); } ...

Discover the two words before and after a span element using jQuery

data-color="red"I am looking for 2 words before and after the span tags. Here is the html code: <p>This pathway has an inner and an outer wall. The pressure <span data-color="red" class="highlight">inside the</span> eye closes the tun ...

Issues with the audio on ExpressJS video streaming can be quite vexing

After multiple attempts to run an ExpressJS web server that serves videos from my filesystem, I've encountered a frustrating issue. Whenever a video is played, there are constant popping sounds and eventually the audio cuts out completely after 3-10 m ...

Encountered an uncaughtException in Node.js and mongoDB: User model cannot be overwritten once compiled

Currently, I am utilizing this import statement const User = require("./Usermodel")' However, I would like to modify it to const User = require("./UserModel") Despite my efforts to align the spelling of the import with my other i ...

Implement styling based on user input - Transmit form data via PHP to designated email address

My form allows people to provide their details and share their current timetable. I then group them based on suitable times The PHP form currently prints either 'work' or 'free' into a table cell, based on user selection in the form, a ...

Steps to trigger a modal (bootstrap 5) in react upon clicking a cell within the Full Calendar interface

My goal is to trigger a modal window using Bootstrap 5 (not React-Bootstrap library) when clicking on a day in the FullCalendar Component in React. I attempted to access the modal by using jQuery's $, but encountered the error message "$ is not a fun ...

How can I show only the final four digits of an input field using Angular Material and AngularJS?

As a newcomer to Angular Material and Angular JS, I am striving to create an md-input field that displays only the last 4 digits in a masked format, such as "********1234". While my experience is currently limited to using md-input password fields where ...

What is the best way to extract information from a JSON object?

I am currently utilizing the JSON.js library provided by JSON.org. <% JSONReturn = GetDistance(Sample) // this function returns a string in JSON format (specifically from the ArcGIS server Solve Route function) JSONObject = JSON.parse(JSONReturn,"Tota ...

What is the best way to combine a require statement and a function in CoffeeScript?

I'm trying to accomplish this task: require('./config/enviroment.js')(app, express); However, I am unsure of the proper method... I attempted: require './config/routes.js'(app, routes) -> Resulting in: require('./conf ...

.NET CORE web api fails to recognize updates

Currently, I am developing a VueJS application with the back-end in .NET Core 2.2. I have been working on this project for a few months, but after updating from version 2.0 to 2.2, I encountered some issues. One major problem is that the changes I make in ...

Prevent the use of the + or - symbols within the body of a regular expression when

function validateNumberInput(){ userInput = document.getElementById('txtNumber').value; var numberPlusMinusRegex = /^[\+?\-?\d]+$/g; if (userInput.match(numberPlusMinusRegex)) { alert('Vali ...

Using Laravel along with Inertia.js and Vue, we can easily determine whether a user is logged in

I am currently using Laravel along with Inertia.js for my project implementation. I am facing an issue where I want to display a div element containing some user details in the navbar only if the user is logged in. However, the div should not appear if the ...

What is a way to retain the value of a variable after a request, while starting off with a different value on the initial load?

In my Flask application, users have the option to choose a specific time period with a start date and an end date. When the page initially loads, I want the start date to default to the first day of the current month and the end date to be the current day. ...