eddiemf / vue-scrollactive

Lightweight and simple to use vue component that highlights menu items as you scroll the page, also scrolling to target section when clicked.
MIT License
542 stars 70 forks source link

specifying scrollContainerSelector causes scroll to jump back to the top #89

Open nicolaszu opened 3 years ago

nicolaszu commented 3 years ago

Hi,

I'm currently using vue-scrollactive with a custom selector string so that I can use it to scroll a div with overflow. Code looks as as follows:

Navigation Bar

<scrollactive class="my-nav" scrollContainerSelector="#main-scrollable-content">
    <a href="#intro" class="scrollactive-item nav-item ">
      Intro
    </a>
    <a href="#summary" class="scrollactive-item nav-item ">
        Summary
    </a>
</scrollactive>

Overflow Div

<div id="main-scrollable-content" style="{height:'95vh', overflow-y :'auto'}">
   <div id='intro' />
   <div id='summary' />
</div>

I'm getting an issue where clicking on a scrollactive item does scroll down and activate the correct href but it immediately jump back to the top. See Gif:

scrollactive

Would appreciate any help solving this! Happy to submit a PR if someone could point me in the right direction.

Thanks.

xiongzhong commented 3 years ago
    getItemInsideWindow() {
      let currentItem;

      forEach(this.items, ({ menuElement, section }, index) => {
        const isFirstItem = index === 0;
        // There is a precision problem here. For example, an error in matching occurs when the following happens.
        const distanceFromTop = this.scrollContainer.getDistanceFromTop(); // 1820.800048828125
        const targetOffsetTop = this.getOffsetTop(section) - this.offset; // 1821
        const isScreenPastSectionStart = distanceFromTop >= targetOffsetTop;
        const isScreenBeforeSectionEnd = distanceFromTop < targetOffsetTop + section.offsetHeight;
        const isScreenInsideSection = isScreenPastSectionStart && isScreenBeforeSectionEnd;

        if (isFirstItem && this.highlightFirstItem) {
          if (isScreenBeforeSectionEnd) currentItem = menuElement;
        }

        if (this.exact && isScreenInsideSection) currentItem = menuElement;
        if (!this.exact && isScreenPastSectionStart) currentItem = menuElement;
      });

      return currentItem;
    },