smooth-scrollbar icon indicating copy to clipboard operation
smooth-scrollbar copied to clipboard

Additional Scrolling Methods

Open aight8 opened this issue 8 years ago • 7 comments

Inspired by https://github.com/yiminghe/dom-scroll-into-view

You can't use this library since smooth-scrollbar use animation for scrolling.

The only additional functionality is to add an instance method that accept a node with some usefull parameters to improve user experience (onlyScrollIfNeeded, offsetTop etc. -> see dom-scroll-into-view).

Would be very cool when this library would support this!

aight8 avatar Apr 04 '16 14:04 aight8

You mean I need add an instance method that acts like scroll-into-view? In my view this should be done by users: you got the element and measured its position, then scroll to it through instance#scrollTo method. I want this library to focus on scrolling itself.

idiotWu avatar Apr 04 '16 15:04 idiotWu

Yeah I'm currently on it to figure out how to handle this. It's a little bit complicating and mess up my component with scrolling logic.

The Element.scrollIntoView - method which is supported by the browser not works here so the scrollbar component should carry over this job somehow imo. scroll-into-view works neither since it can only work with the browser based scrolling.

For example: How do you want solve anchor problems (imagine you have a list of anchor links as list of contents)? You have to work with different data and create a lot of code:

  • scrollbar.getSize() -> .content and .container
  • targetNode.offsetTop/offsetLeft

Additionally there is no method to fetch the current scrolling offset trough the instance API. I listen with "addListener" method and save the data from the event somewhere temporarly. It's like listening to the window.onResize method instead of fetch the data direct from window Object when you need it. It feels not so clean.

aight8 avatar Apr 04 '16 16:04 aight8

Anchor is a big problem that I don't know how to solve it properly, as for current offset, you can get it from instance.offset property (sorry for the lack of api docs).

idiotWu avatar Apr 05 '16 14:04 idiotWu

@aight8 Hey buddy, I've added scrollIntoView() method support in version 5.3.0, check the documents here and give me a feedback :)

idiotWu avatar Apr 14 '16 12:04 idiotWu

Sorry don't see that post.

Nice! I found some differences to my current implementation which have a slightly other behavior.

When the target element is fully inside of the container: do nothing (except alignWithTop is true) When the target element is partially outside of the container: Scroll the outside part into the container + offsetBottom px (in your current implementation it happen nothing only when the target element is fully outside of the container + it scrolls not only as much as needed, it try to align it to the top -> like mine alignWithTop option) Same for the top but then use offsetTop as padding px. When the alignWithTop option (act's like in your implementation) is set to true then try to align the target element to the top + offsetTop px. (when possible) That's useful for anchors. Currently always even if it's in the container - but your option onlyScrollIfNeeded can stay for this use case.

What you think?

This code is only for vertical scrolling (but that was my needs):

let scrollbar = this.getInstance();

        const offsetTop = config.offsetTop || 0;
        const offsetBottom = config.offsetTop || 0;
        const alignWithTop = config.alignWithTop || false;

        let nodeOffset = {
            y: node.offsetTop
        };
        let sbOffset  = scrollbar.offset;
        let { container } = scrollbar.getSize();

        let nodeRect = node.getBoundingClientRect();
        let nodeRectStart = nodeOffset.y;
        let nodeRectEnd = nodeRectStart + nodeRect.height;

        let vpRectStart = sbOffset.y;
        let vpRectEnd = vpRectStart + container.height;

        let newScrollbarY;

        if (alignWithTop === true) {
            newScrollbarY = node.offsetTop - offsetTop;
        } else {
            if (nodeRectStart < (vpRectStart + offsetTop)) {
                // element it partially out of view on top OR to little top offset
                newScrollbarY = node.offsetTop - offsetTop;
            }
            if (nodeRectEnd > (vpRectEnd - offsetBottom)) {
                // element it partially out of view on bottom OR to little bottom offset
                newScrollbarY = nodeRectEnd - container.height + offsetBottom;
            }
        }

        if (newScrollbarY) {
            scrollbar.scrollTo(0, newScrollbarY, 200);
        }

aight8 avatar Apr 19 '16 21:04 aight8

Hmm...I checked Element.scrollIntoViewIfNeeded documents again, it appears that I misunderstood the behavior.

I can, however, do as much as dom-scroll-into-view plugin is. But I'm afraid this scrollbar plugin would be too heavy that I have to call it a library.

I am busy with my school courses currently, if you insist that we should completely support this feature, you can make some PRs and I'll check it once I have time :)

Thanks in advance.

idiotWu avatar Apr 20 '16 04:04 idiotWu

I have the same problem/needs and this functionality would be awesome !

HectorLS avatar Nov 16 '17 16:11 HectorLS