Coder Social home page Coder Social logo

eddiemf / vue-scrollactive Goto Github PK

View Code? Open in Web Editor NEW
544.0 8.0 70.0 1.11 MB

Lightweight and simple to use vue component that highlights menu items as you scroll the page, also scrolling to target section when clicked.

License: MIT License

JavaScript 28.51% Vue 54.57% HTML 13.36% CSS 3.56%

vue-scrollactive's Issues

Bug: Last item has highlighted class on load

On page load the last item that has a binding receives the active class, which is wrong. When I scroll for just 1px it will be fixed. What's the problem?

<scrollactive v-if="showNavText" active-class="router-link-exact-active" :offset="80" :duration="600">
<a class="navigation-text-desktop scrollactive-item" href="#home">News</a>
<a class="navigation-text-desktop scrollactive-item" href="#links">Links</a>
<a class="navigation-text-desktop scrollactive-item" href="#community">Community</a>
</scrollactive>

data-section-selector does not work

<scrollactive :offset="50" tag="div" :alwaysTrack="true" :modifyUrl="false" :exact="true">
    <span data-section-selector="#subsection-1" class="scrollactive-item">test1</span>
    <span data-section-selector="#subsection-2" class="scrollactive-item">test2</span>
    <span data-section-selector="#subsection-3" class="scrollactive-item">test3</span>
</scrollactive>
<div id="subsection-1">
    <h2>subsection-1</h2>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. 
    Ab, aperiam atque consequuntur culpa cum dolorem doloribus earum error fuga laborum 
    molestias neque nesciunt quaerat quas rem veniam voluptatum! Minus, vel?</p>
</div>
<div id="subsection-2">
    <h2>subsection-2</h2>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. 
    Ab, aperiam atque consequuntur culpa cum dolorem doloribus earum error fuga laborum 
    molestias neque nesciunt quaerat quas rem veniam voluptatum! Minus, vel?</p>
</div>
<div id="subsection-3">
    <h2>subsection-3</h2>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. 
    Ab, aperiam atque consequuntur culpa cum dolorem doloribus earum error fuga laborum 
    molestias neque nesciunt quaerat quas rem veniam voluptatum! Minus, vel?</p>
</div>

Snímek obrazovky 2020-07-16 v 10 10 22

Problem with entering hashed adresses

My problem is that when I enter anchored position on page, eg. /#contact, it always renders at the top, not in the given position, when I disable scrollactive the problem ends.

Local Import Get Error

Hi,
Im getting an error when I import local;

import VueScrollactive from 'vue-scrollactive'; export default { components: { Scrollactive: VueScrollactive, }, }
[Vue warn]: Failed to mount component: template or render function not defined.

Is there a solution ? Thank you

Package not working if scrollContainer is not provided

Hi!

Since the latest release the plugin stopped working if there is no scrollContainer provided. The issue is here:
06dfcb3#diff-4959140d7c2bf6ca765de6d9c393a83cR363

Since this.scrollContainer is always set (it's a computed property, and it's either the one set in props, otherwise window), we try to get the offsetTop of window. Since window does not have such property, it returns undefined. Some number (yPosition) minus undefined is NaN. So our script breaks.

Because there might be a few other elements without offsetTop properties, I would not suggest checking for whether the container is window or not, rather check for the availability of offsetTop.

Something like this would probably work fine:

if (this.scrollContainer && typeof this.scrollContainer.offsetTop === 'number') {
  return yPosition - this.scrollContainer.offsetTop;
}

Different offset for different elements

I have a use case where I need a different :offset depending on which link is clicked. I've tried dynamically setting a data property depending on currentTarget but it doesn't seem to work. Is there a way to do this I'm unaware of? If not this would be a really helpful implementation.

SSR Support

Hi. This was exactly what I was looking for, but I'm working on a project that uses SSR. I'm new to Vue, but I assume since this uses window that SSR won't work out of the box. I know there is a way that fakes window to make most Vue plugins to work on the server side, but I'd like to avoid this, if possible. I noticed vue-scrollto plugin got it working with this simple fix. They just changed
if (window.Vue)... to if (typeof window !== "undefined" && window.Vue)...

Could something like that be easily applied to this project?

Multiple items with the same link only got is-active at the last item

If the item in menu point to the same link, only the last item got the is-active class when page scroll to that section.

E.g.

<div class="submenu-links">
  <a href="#highlights" class="scrollactive-item submenu-item" v-if="preset.data.infoHighlights && preset.data.infoHighlights.length">Highlights</a>
  <a href="#itinerary" class="scrollactive-item submenu-item">Itinerary</a>
  <a href="#priceinfo" class="scrollactive-item submenu-item">Pricing info</a>
  <a href="#priceinfo" class="scrollactive-item submenu-item">Pricing info 2</a>
  <a href="#tripinfo" class="scrollactive-item submenu-item">Trip info</a>
</div>

Only Pricing info 2 got is-active class.

Expected Behavior:
Both Pricing info and Pricing info 2 should got is-active class.

Follow Vue component naming convention

https://vuejs.org/v2/style-guide/#Priority-A-Rules-Essential-Error-Prevention

Current usage

<scrollactive></scrollactive>

Export the component so it will be used with a hyphen

<scroll-active></scroll-active>

Issue

Some editors (Such as VSCode) will see this as an invalid element. If the component follows the naming convention of having a hyphen, it will just be seen as a custom element ready to be picked up by some javascript.

Specifically with my editor, I had a problem with two nav elements being rendered. Turns out, I had forgotten to put a slash in the end tag, resolving in the next element being included in a secondary nav tag like so:

<scrollactive>
    <a href="...">...</a>
    <a href="...">...</a>
    <a href="...">...</a>
<scrollactive>
    
<a href="...">...</a>

Result:

<nav class="scrollactive-nav">
    <a href="..." class="scrollactive-item">...</a>
    <a href="..." class="scrollactive-item">...</a>
    <a href="..." class="scrollactive-item">...</a>
    <a href="..." class="scrollactive-item">...</a>
    <a href="..." class="scrollactive-item">...</a>
    <nav class="scrollactive-nav">
        <a href="..." class="none-scroll-item">...</a>
    </nav>
</nav>

Edit: Added link to style guide documentation

How to listen currentItem

Hello,

I have more a question than issue. I would like to listen "currenItem" on the itemchanged function. I just don't know how to pass the element...

This is more or less what I have in mind: v-on:itemchanged="update(currenItem)"

Sorry for my noobie question.

Thanks

Previous / next functionality

Hi,

Is there any way you could programmatically add a previous and next button so a user could navigate to the previous en next element?

scrollContainerSelector do not apply in Vue.use(options)

Hi!
My site have overflowed 100vh container and I need set it to scrollContainerSelector globaly but it is not working.
This work only in component prop : scrollactive( scrollContainerSelector='#appScroll').

I trying do that just like that
Vue.use(VueScrollactive, {
scrollContainerSelector: '#appScroll',
});

Error "You must give your menu items a class of 'scrollactive-item' in order to track them."

Hi, I'm new to VueJS.

I tried to use it but it gives me Error: You must give your menu items a class of 'scrollactive-item' in order to track them.
But I already gave the class name to the <a> tag,
I tried to call the dynamicItemsFunction after but the same error persists.
When the link is clicked, I get this error
Cannot read property 'substr' of undefined
from:
var targetDistanceFromTop = this.getOffsetTop(document.getElementById(event.target.hash.substr(1)));

below is my html code,
Thank you for your help!

<div class="menu-wrapper" :style="{marginTop: 0.117 * bodyWidth + 'px'}">
    <div class="catalogue">
        <scrollactive ref="scrollactive" :offset="offset" :always-track="alwaysTrack" :duration="duration" :click-to-scroll="clickToScroll" :bezier-easing-value="easing">
            <a v-for="aCat in cataArr" v-bind:key="aCat" class="scrollactive-item" href="'#' + aCat.substr(0, 10)">
                <div class="each-cat">
                    {{aCat}}
                </div>
            </a>
        </scrollactive>
    </div>
    <div class="items-wrapper">
        <div class="each-cat-item" v-if="formatCats.length>0" v-for="aCat in formatCats" v-bind:key="aCat" :id="aCat.substr(0, 10)">
            {{aCat}}
            <div class="each-item" v-for="anItem in posts[aCat]" v-bind:key="anItem">
                <div class="item-img" v-if="anItem.photos && anItem.photos.length > 0" @click="jump(anItem)">
                </div>
            </div>
        </div>
    </div>
</div>

Multiple scrollactive on the page cause glitches

Hi there. Awesome plugin, but unfortunately I found out that it has issue, if I am trying to use multiple scrollactive on single page. For example, I have 2 navigations, main and mobile. I want scrollactive on both. If I try that, then I have glitches. For example if you set :duration="1000" then scrollbar will jerk. Or, even :duration="100" will not work at all (small values).

Is there's a way to fix it?

Active class applied on page load

Hi, I'm having an issue where the active-class is applied on page-load but I only want it applied after the user clicks the link. I've tried :highlightFirstItem="false", even though this is the default setting, but it didn't work. Am I wrong in thinking this is the setting for it? Is there a way around this issue I'm not aware of?

Here's the code I'm using:

<scrollactive
    active-class="nav-selected"
    :offset="0"
    :duration="1000"
    bezier-easing-value=".5,0,.35,1"
    :modifyUrl="false"
>
    <a href="#smooth-scroll" class="scrollactive-item"
        >Smooth Scroll</a
    >
</scrollactive>
.nav-selected {
    font-weight: bold;
}

The text is bold on page-load, if I scroll at all, the active class is removed and doesn't respond to any scrolling (how I want it) but then works as it should on click:

Example

Sections out of the viewport

Hi @eddiemf, is there any option to "active" the item in menu only if the trackable sections are really in viewport?

Example: I have 5 sections in sequence, but I'd like to activate menu items only when the scroll reaches the sections 1, 3 and 5. So, if I reach section 2 or 4, no items in menu should be active.

Thanks and congrat for the very nice plugin.

scrollactive inside other scrollactive

Hello! I need menu like this:
https://excelsiorer.github.io/portfolio/instalations.html

This i make on vanila js. Now i try make it on vue, and use this library.

I use this markdown:
`


  • Project 1


  • Submenu 1-1


  • Submenu 1-2


  • Submenu 1-3


  • Submenu 1-4


  •     <li>
            <a href="#project-2" class="scrollactive-item"> Project 2 </a>
            <scrollactive active-class="submenu--active" tag="ul">
                <li>
                    <a href="#submenu-2-1" class="scrollactive-item"> Submenu 2-1 </a>
                </li>
                <li>
                    <a href="#submenu-2-2" class="scrollactive-item"> Submenu 2-2 </a>
                </li>
                <li>
                    <a href="#submenu-2-3" class="scrollactive-item"> Submenu 2-3 </a>
                </li>
                <li>
                    <a href="#submenu-2-4" class="scrollactive-item"> Submenu 2-4 </a>
                </li>
            </scrollactive>
        </li>
    </scrollactive>`
    

    but both classes add only on second scrollactive tag.
    How i can change it?

    Does not work in hash mode

    I get

    DOMException: Failed to execute 'querySelector' on 'Document': '#/en/scrolltest/' is not a valid selector.

    when vue-router is in hash mode. Works perfectly in history mode

    Problem Unknown custom element: <scrollactive> when trying to use the component

    Hello, after doing the installation of the package using npm, and configure it as explained in the documentation. I try to use it and it throws me this error:

    vue.esm.js?efeb:610 [Vue warn]: Unknown custom element: - did you register the component correctly? For recursive components, make sure to provide the "name" option. found in
    ---> at src/views/Home.vue
    at src/App.vue

    Multiple active class

    Hi !
    Thanks for your project. I use it for my work but i found a problem about the active class navigation.

    To reproduce it :
    <scrollactive id="nav-items" class="my-nav" active-class="active" v-on:itemchanged="onItemChanged" :offset="90" :duration="500" :modify-url="false"> </scrollactive>

    My navigation looks like :
    <nav class="scrollactive-nav my-nav" id="nav-items"><a href="#introduction" class="scrollactive-item">Introduction</a><a href="#factsDemandsProcedure" class="scrollactive-item">factsDemandsProcedure</a><a href="#motifs" class="scrollactive-item">motifs</a><a href="#dispositif" class="scrollactive-item">dispositif</a><a href="#signature" class="scrollactive-item active">signature</a></nav>

    Each sections have the following template :
    <section id="introduction" class="part"><p>My content ...</p></section>

    Each section has different height. And it's the problem because dispositif and signature section have a little height and place at the end of the document.

    Case reproduction :

    • click on the last item signature
      => scroll to the end of the page
      => active the class
    • scroll up
      => last item signature have always active class
      => item motifs has active class

    I bind the itemchanged methods to debug then i noticed something. My console.log not appears when i click on the last section probably because the last section can not be reached by the window's offset.

    Thanks for your answer.

    Error with detached element

    Hi,

    Thanks for the plugin!

    An error I encountered: I use scrollActive on an element which is in a tab. When I switch tabs and scroll, I get the following error:

    vue-scrollactive.js?ce7a:1088 Uncaught TypeError: Cannot read property 'offsetHeight' of null
        at eval (vue-scrollactive.js?ce7a:1088)
    

    which is this line:

    var isScreenBeforeSectionEnd = window.pageYOffset < _this.getOffsetTop(target) - _this.offset + target.offsetHeight;
    

    I guess the inactive tab is detached by the framework I use (Quasar) but not destroyed (because I use the keep-alive property of tabs, which keeps the rendered HTML in memory), so scrollActive is still listening to events and doing things. Not sure if you can fix it without me worrying about it, or if I should call some method to put it on hold while the tab is inactive?
    Thank you.

    IE11 isn't supported.

    IE11 isn't supported. IE message -> SCRIPT5009 - Object promise not defined.
    Btw good work. Nice plugin. :)

    Have a question

    Great plugin for Vue, but i have trouble with matching URL

    I have a page with section
    #about
    #prices

    URL must be /courses/1/#about
    but after clicking on item i have only /#about

    Nuxt with dynamic routring

    dist/vue-scrollactive.min.js is stuck on old release

    When installing the plugin as described in the readme, it seems like vue-scrollactive is stuck on v0.9.1, which doesn't support the new feature added in v0.9.2.

    When comparing the minified file between the two releases,git diff v0.9.1 v0.9.2 dist/vue-scrollactive.min.js, we can see that there is no difference between these two releases.

    Related problems:

    • When installing the plugin, the main file that is imported as a plugin is dist/vue-scrollactive.min.js. This could be replaced with src/index.js without any problems, as the file will (usually, in most setups) be minified by the build setup using the plugin. This will also allow the user (in this case, me) to see the source easier while debugging the code.
    • The pre-commit hook that is supposed to make dist/vue-scrollactive.min.js semi-readable does not make sure we have actually built dist/vue-scrollactive.min.js from the latest sources before committing.

    Navigation breaks when using scrollactive AND router.

    Hi guys

    I have a page with a few different sections (all of these have a vue-scrollactive linking). When clicking on an item (let's say from #team), a detailpage opens (= route navigated, #/team/sandrooco).
    Then, when clicking on a back button, this.$router.go(-1); executes. The problem: Vue will not recognize #team as route (because it doesn't exist...) and the user will be lost (no navigation possible).

    I hope you understand it, it's quite complicated.

    I use vue-scrollactive 0.5.1 and vue 2.5.2.

    Can I do it not just by hash, but also by className

    Can I do it not just by hash, but also by className. For example, set data-*

    <scrollactive class="my-nav">
      <span data-class="a" class="scrollactive-item">Home</span>
      <span data-class="b" class="scrollactive-item">About Us</span>
      <span data-class="c" class="scrollactive-item">Portfolio</span>
    </scrollactive>
    
    <div class="container">
      <p class="a">a</p>
      <p class="b">b</p>
      <p class="c">c</p>
    </div>
    

    A bug? two menu item hightlight at same time

    See below screenshot from online demo, You should recreate the issue with below steps:

    1. Open demo page
    2. Click on section 2
    3. Scroll up a little to section 1.

    Fix:

    onScroll(event) {
            this.currentItem = this.getItemInsideWindow();
            if (this.currentItem !== this.lastActiveItem && this.currentItem) {
              this.removeActiveClass();
              this.$emit('itemchanged', event, this.currentItem, this.lastActiveItem);
              this.lastActiveItem = this.currentItem;
            }
            // Current item might be null if not inside any section
            if (this.currentItem) {
              this.removeActiveClass();
              this.currentItem.classList.add(this.activeClass);
            }
          },
    

    I also added an empty check on line 3 because sometimes, i found the currentItem is undefined but the itemchanged even still triggered.

    screen shot 2018-05-21 at 6 24 31 pm

    modifyUrl setting not useful

    show my code

    <scrollactive
          :modify-url="false"
          :always-track="true"
          :duration="800"
          bezier-easing-value=".5,0,.35,1"
    >
          <h-navbar
                  :slider="{
                    width: 50,
                    height: 4,
                    color: '#FF4A83',
                  }"
                  :tabs="tabs"
          >
                  <a :slot="`tab${index}`" :href="`#floor${index + 1}`" v-for="(item, index) in tabs" :key="index">{{item}}</a>
          </h-navbar>
    </scrollactive>
    

    as i set props modifyUrl to false
    but i find noting happend
    the url is also be modifyed,
    like: http://localhost:8080/#/course/courseList?courseId=COURSEID to http://localhost:8080/#/floor1
    i do something error?

    how to prevent replacing the URL with tag

    this is what happens:

    • The last part of whatever my URL is is replaced with the # tag

    2020-10-08 09 44 18

    • Surely the intended behaviour is that the # should be appended to the URL...?

    eg. me.me/background when a link is clicked: me.me/background#about-me

    instead of background being replaced... right?

    Set offset with callback? Or update on window resize somehow

    As per the title. It would be fantastic to accommodate for a changing navbar height – for situations where precise positioning is needed.

    This could be easily done with a callback or if the offset prop listened for changes on a data value – would that be efficient?

    I’m trying to set :offset="offset" with:

        getNavHeight() {
          let navHeight = document.getElementById('header').offsetHeight + document.getElementById('subheader').offsetHeight
          this.offset = navHeight * 1;
        }
    

    but not having any luck

    vue-scrollactive inside a viutify dialog doesn't work

    hi, i am trying to use vue-scrollactive inside a viutify dialog / modal but it doesn't work. I think it doesn't iterate over the dialogue.

    try scrollContainerSelector but it doesn't work either.

    I want to clarify that if it works for me outside the dialog / modal

    also when I click on an it doesn't work either

    could you help me please? thanks!

    image

    How to adjust the lead for the next highlight?

    Nice package! Thank you for writing it - it has saved me some time and trouble from writing my own.

    I'm hoping my feedback is constructive. I'd like to discuss a couple of things I ran into when implementing this in a new client site. I added a CodePen example to follow along with here: https://codepen.io/markadrake/pen/xWebxQ

    I want to highlight the next item as soon as it's visible

    Meaning, once section two has scrolled into view then "two" should highlight in the menu. This too could benefit from an offset so that we can say "once this element is at least 100px visible, time to switch the active class".

    There's already an offset parameter, and it works well when clicking a link and scrolling to the desired element on the page. But I need control over when highlighting occurs and quite possibly, an offset value of its own.

    Unit options for the offset

    Currently the offset isn't just a number value - it's a specific number of pixels. However, in implementation I may want more control over this value especially when considering the design changes that can occur between breakpoints, and the user's zoom level. It would be nice to provide different values such as:

    • A percentage (50%)
    • An em/rem value (4rem)

    Or even take a targe element, calculate it's height, and use that as the value or part of the calculation of the value. This would have to subscribe to the window resize event to keep it in check.

    What's causing the bounce back between items on the page?

    Click on "Six" and you should see it jump back to five. After a while of testing, you may notice other items in the menu will start to behave this way - but "Six" does it everytime.

    Although I couldn't replicate it any more here, in a site I'm building and using this on it's even more pronounced as all of the menu items scroll to the right place, set the appropriate highlight, but after the scroll animation is complete it will highlight the previous entry instead.

    Apply active class to an element when none are in the viewport

    Hi, I'd like to be able to apply the active class to the first element in the nav when none of the sections are in the viewport, is this possible?

    At the moment I'm adding the active class in my markup but when the component is mounted it removes all instances of the class.

    Here's an example of what is happening right now (I'd like "popular" to be active before a sections is scrolled into view):

    oct-06-2018 21-27-24

    Would you consider adding this via an option? Something like firstItemActive?

    I'm happy to submit a pull request.

    Recommend Projects

    • React photo React

      A declarative, efficient, and flexible JavaScript library for building user interfaces.

    • Vue.js photo Vue.js

      🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

    • Typescript photo Typescript

      TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

    • TensorFlow photo TensorFlow

      An Open Source Machine Learning Framework for Everyone

    • Django photo Django

      The Web framework for perfectionists with deadlines.

    • D3 photo D3

      Bring data to life with SVG, Canvas and HTML. 📊📈🎉

    Recommend Topics

    • javascript

      JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

    • web

      Some thing interesting about web. New door for the world.

    • server

      A server is a program made to process requests and deliver data to clients.

    • Machine learning

      Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

    • Game

      Some thing interesting about game, make everyone happy.

    Recommend Org

    • Facebook photo Facebook

      We are working to build community through open source technology. NB: members must have two-factor auth.

    • Microsoft photo Microsoft

      Open source projects and samples from Microsoft.

    • Google photo Google

      Google ❤️ Open Source for everyone.

    • D3 photo D3

      Data-Driven Documents codes.