Vue: offsetTop всегда возвращает 0

#javascript #vue.js

#javascript #vue.js

Вопрос:

Я пытаюсь исправить элемент, когда пользователь прокручивает его, но у меня проблема. По какой-то причине мой элемент (в моем случае это панель навигации) всегда возвращает 0, несмотря на то, что его высота составляет примерно 300 пикселей более или менее.

Это мой смонтированный метод, в котором я выполняю вычисления, как вы видите, я регистрирую stickyTop на консоли, всегда 0.

Я пробовал с offsetTop и getBoundingClientRect().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 amp;amp; link.subLinks
      );
    },

    visibleLinks: function () {
      return this.globals.navLinks.filter(
        (link) =>
          (link.isVisible amp;amp; !link.hasSublinks) ||
          (link.isVisible amp;amp; link.hasSublinks amp;amp; 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>
  

Комментарии:

1. когда уже импортируется jQuery… смотрите api.jquery.com/offset

Ответ №1:

Скорее всего, у вас есть другой элемент (дочерний элемент window, body и т.д.), Для свойства overflow которого установлено значение auto или scroll. Это элемент, который вам нужно получить offsetTop из.

Используйте средства разработки, чтобы найти элемент, который owns the scroll bar , а затем используйте ссылку на этот элемент вместо window .

Комментарии:

1. как я могу найти элемент, которому принадлежит полоса прокрутки с помощью devtools в Firefox??

2. Используйте средства разработки «селектор элементов» и укажите на div, в котором есть полоса прокрутки, затем начните просматривать css для scroll: auto для каждого родительского элемента. Вы также можете проверить значение offsetTop, как только найдете его. Затем выделите этот элемент в своем коде, используя ссылки, идентификаторы или селекторы.