Bernard Doci
Bernard Doci

Reputation: 769

Scroll down to element with a class name on Vuejs component

I have a component with unordered list and what I want to do is when component is loaded I want the component to be scrolled down to

  • element with a class name 'actual-month' so it can be visible.

    <b-card no-body header="<i class='fa fa-align-justify'></i> Unorderd List"  style="height: 680px">
              <b-tabs card pills>
                  <b-tab v-for="debt in user_debts"  :title="Debts list"  :key="debt.id" class="card-height">             
                     <table class="table table-sm amortization-header header-fixed">
                      <thead>
                          <tr>
                            <th>Month</th>
                            <th>Balance</th>
                            <th>Paid</th>
                            <th>Debt</th>
                            <th>Nominal Interest</th>
                          </tr>
                      </thead>
                      <tbody> 
                        <tr v-for="month in amortization.schedule" :class="{'actual-month' : month.month == amortization.actual_month}">
                          <td>{{month.month}}</td>
                          <td>{{month.balance.toLocaleString()}}<span class="total">€</span></td>
                          <td>{{month.monthly_payment}}<span class="total">€</span></td>
                          <td>{{month.principle}}<span class="total">€</span></td>
                          <td>{{month.interest}}<span class="total">€</span></td>
                        </tr>
                      </tbody>
                    </table>
                  </b-tab>
              </b-tabs>
            </b-card>
    
  • Upvotes: 5

    Views: 14665

    Answers (4)

    craig_h
    craig_h

    Reputation: 32724

    There are probably a few ways to do this, but I would place it in a mixin so I could reuse it, so:

    const scroller = {
      methods: {
        scrollToClass(className) {
          // Get the first element with the given class name
          let el = this.$el.querySelector(className)
          // Get the bounding rectangle so we can get the element position position
          let rect = el.getBoundingClientRect()
          // Scroll to the element (using x and y axis)
          window.scrollTo(rect.left, rect.top)
        }
      }
    }
    

    Then you can use it in your mounted hook (when this.$el first becomes available) like so:

    new Vue({
      el: '#app',
      mixins: [scroller],
      mounted() {
        this.scrollToClass('.actual-date')
      }
    })
    

    Here's the JSFiddle: https://jsfiddle.net/ha9hm9xe/

    Upvotes: 4

    Consta Gorgan
    Consta Gorgan

    Reputation: 589

    The other answers didn't quite work for me - I was getting the following error: cannot access property scrollIntoView of undefined. To get around this you can add a setTimeout.

    Let's suppose you want to scroll to the first element containing the class invalid when submitting a form:

    const someComponent {
      ...
      methods: {
        validateForm() {
          if (formValid) {
            // submit form
            ...
          } else {
            // show errors
            ...
            // and scroll to the first one
            this.scrollToInvalidField();
          }
        },
        scrollToInvalidField() {
          // Without this setTimeout, an "undefined" error is thrown.
          setTimeout(() => {
            let el = this.$el.getElementsByClassName('invalid')[0];
            el.scrollIntoView();
          }, 0);
        },
      },
      ...
    }
    

    And of course, if you want a smooth scroll { behavior: 'smooth' } can be passed as a parameter to the scrollIntoView() function as @digout mentioned in his answer.

    Upvotes: 0

    digout
    digout

    Reputation: 4252

    Adding to Julien's answer, for a lot of use cases, animating automated actions such as jumping to a part of a page, smooth scrolling improves ux:

    el.scrollIntoView({ behavior: 'smooth' })
    

    Upvotes: 2

    Julien
    Julien

    Reputation: 1238

    You can use scrollIntoView:

    mounted: function (){
      var el = this.$el.getElementsByClassName("actual-month")[0];
      el.scrollIntoView();
    }
    

    Upvotes: 10

    Related Questions