Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vuetify Tabs change active when scroll

I've vuetify tabs implemented with vue-scrollto that when you click a tab it will scroll to a position.

       <v-tabs
          centered
          grow
          color="#009EE2"
        >
          <div class="slider-background" />
          <v-tabs-slider />

          <v-tooltip
            bottom
            v-for="(tab, key) in tabs"
            :key="key"
            color="#009EE2"
          >
            <template v-slot:activator="{on}">
              <v-tab
                v-on="on"
                v-scroll-to="{
                  el: tab.scrollTo,
                  container: scrollContainer,
                  duration: 300,
                  easing: 'linear',
                  offset: -120,
                  force: true,
                  cancelable:true
                }"
              >
                <v-icon v-text="tab.icon" />
              </v-tab>
            </template>
            <div class="v-tooltip-arrow" />
            <span>
              {{ $t(tab.tooltipText) }}
            </span>
          </v-tooltip>
        </v-tabs>

So what I want to achieve now is that when scrolling the active tab changes depending on the position.

I've searched for days and I haven't found anything. documentation

Is there a way without using JQuery?

Result example with JQuery: http://jsfiddle.net/cse_tushar/Dxtyu/141/

like image 776
Fabio Venturi Pastor Avatar asked Mar 03 '23 21:03

Fabio Venturi Pastor


1 Answers

By combining the href attribute for tabs, and an intersection observer, you can accomplish this.

Here's a rudimentary, but working, pen: https://codepen.io/Qumez/pen/VwYEapg

Effectively, what we're doing here is assigning an anchor to each tag, and tying that to a data property. Then, we have a span at the bottom of the page with an intersection observer, using Vuetify's v-intersect wrapper:

<span v-intersect ="handleIntersect">Page will automatically scroll to tab-3 when this span is in view</span>

This intersect wrapper calls a user-defined method (in this case, handleIntersect) to update the tab:

        handleIntersect(entries, observer) {
            if(entries[0].isIntersecting) {
                this.tab = "tab-3"
            }
            else {
                this.tab = "tab-1"
            }
        }

For your use case, maybe each item that would change a tab based on its viewport position would need to call a given function with an argument for which tab to set. That's not much of a stretch from where this Pen is currently.

Note: I've never used IntersectionObserver and I'm not certain if isIntersecting is the best way to detect an element's existence in the viewport, so do your own research and testing before implementing this in production code :)

like image 75
Tanner Avatar answered Mar 05 '23 16:03

Tanner