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>