首页 > 解决方案 > Vue:offsetTop 总是返回 0

问题描述

当用户滚动过去时,我试图修复一个元素,但我有一个问题。出于某种原因,我的元素(在我的情况下是导航栏)总是返回 0,尽管或多或少处于 300px 高度。

这是我进行计算的安装方法,如您所见,我正在控制台记录stickyTop,始终为0。

我尝试使用offsetTopandgetBoundingClientRect().top并且总是返回 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);
  },

我的完整组件以防万一:

<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>

标签: javascriptvue.js

解决方案


您很可能有另一个元素(窗口、正文等的子元素),其溢出属性设置为自动或滚动。那是您需要从中获取的元素offsetTop

使用开发工具来定位那个元素owns the scroll bar,然后使用对那个元素的引用而不是window.


推荐阅读