Yashwardhan Pauranik
Yashwardhan Pauranik

Reputation: 5556

Scroll child div while parent div is position sticky in vue JS

I have a use case for my landing page, where when user enters one of the <section> of the page, the section becomes fixed but the elements inside that <div> starts scrolling. Once the inner div is done scrolling the parent <section> should start scrolling as a normal section and should go away to the top with a scroll.

I've created a similar structure in the jsFiddle below. But not able to achieve the desired feature.

https://jsfiddle.net/8qm67ks9/2/

I wanted to achieve this behavior as presented on this website. Section SS below enter image description here

HTML


... Other sections before

    <section ref="stickyDiv" class="scroller py-sm-128">
      <div class="">
        <div ref="wrapper" @scroll="scrollerListener" class="wrapper-box">
          <div class="d-flex px-sm-128">
            <h3 class="section-heading">Access to all the exclusive opportunities</h3>
            <div class="col-sm-6">
              <img class="img-fluid"
                   src="https://res.cloudinary.com/stack-finance/image/upload/v1663728853/app-assets/v2/mask_group_590_e5gbgr.png"
              >
            </div>
          </div>
          <div class="d-flex px-sm-128">
            <h3 class="section-heading">Access to all the exclusive opportunities</h3>
            <div class="col-sm-6">
              <img class="img-fluid"
                   src="https://res.cloudinary.com/stack-finance/image/upload/v1663728853/app-assets/v2/mask_group_590_e5gbgr.png"
              >
            </div>
          </div>
          <div class="d-flex px-sm-128">
            <h3 class="section-heading">Access to all the exclusive opportunities</h3>
            <div class="col-sm-6">
              <img class="img-fluid"
                   src="https://res.cloudinary.com/stack-finance/image/upload/v1663728853/app-assets/v2/mask_group_590_e5gbgr.png"
              >
            </div>
          </div>
        </div>
      </div>
    </section>

... Other sections in the bottom

Vuejs

  methods: {
    ...
    listenBodyScroll(e) {
      if (this.isMobile) {
        return;
      }

      const stickyDiv = this.$refs.stickyDiv;
      const wrapper = this.$refs.wrapper;
      const dim = stickyDiv.getBoundingClientRect();
      console.log(dim.y, dim.height, '---scrollTop');

      if (dim.y <= 0) {
        if (Math.ceil(dim.height) <= Math.abs(dim.y)) {
          stickyDiv.style.position = 'relative';
          stickyDiv.style.top = 'auto';
          stickyDiv.style.height = 'auto';
          wrapper.style.overflowY = 'hidden';
          wrapper.scrollTop = wrapper.scrollHeight;
          return;
        }

        wrapper.focus();
        stickyDiv.style.position = 'sticky';
        stickyDiv.style.top = '100px';
        stickyDiv.style.height = '100vh';
        wrapper.style.overflowY = 'auto';
      }
    },
    scrollerListener({ target: { scrollTop, offsetHeight, scrollHeight, style } }) {
      if (this.isMobile) {
        return;
      }

      const stickyDiv = this.$refs.stickyDiv;

      if ((Math.ceil(scrollTop) + offsetHeight) >= scrollHeight) {
        stickyDiv.style.position = 'relative';
        stickyDiv.style.top = 'auto';
        stickyDiv.style.height = 'auto';
        style.overflowY = 'hidden';
        console.log('bottom!');
      }
    }
  }

Vue direction v-scroll


Vue.directive('scroll', {
  inserted(el, binding) {
    const f = function(evt) {
      if (binding.value(evt, el)) {
        window.removeEventListener('scroll', f);
      }
    };
    window.addEventListener('scroll', f);
  }
});

Upvotes: 0

Views: 1629

Answers (1)

yoduh
yoduh

Reputation: 14649

There are no secret techniques in web development. Use your browser's inspect tool and check the website's HTML/CSS and see exactly how it works for yourself.

I did this myself and took some of the website's HTML and CSS and recreated a simple version you can see in this codesandbox

Basically, there are two divs of 50% width side by side that exist within the same parent div forcing them to be the same (very large) height. Once you scroll the parent div into view, the image container with position: sticky keeps it in the same relative screen position until you get to the bottom of its parent div where it will then scroll away with the rest of the parent div content.

Upvotes: 1

Related Questions