0

I have a page that had dropdown and images at the top, then a price grid at the bottom (bellow the fold). The price grid is scroll-able inside a div element. On load there is a price on the grid selected, but it is hidden, so you have to scroll the table down to see it.

My problem is, I want to scroll the table within the div element to show the active - but I do not want to scroll the page as well. On load the user should not see anything moving, the table should scroll to show the without them aware (below the fold). When they scroll down the page they should then see the table is displaying the active (selected price) and the table will be scrolled.

const activeRow = $('#prices_table').find('tr td.active');

activeRow[0].scrollIntoView({block: 'center', behavior: 'smooth' });

The problem with my code is it scrolls the user down to the price grid and then scrolls the price grid. I want the user to be left to scroll down to the price grid themselves.

I have found many similar questions, all of these result in the whole page scrolling to the div, and then the div scrolling to show the active class. I need a solution where the page does not scroll.

Sprose
  • 1,255
  • 1
  • 16
  • 20
  • 1
    The problem is in the description: "The Element.scrollIntoView() method scrolls the element on which it's called into the visible area of the browser window." You need to find some other way to scroll it. –  Apr 13 '18 at 07:27
  • 1
    Possible duplicate of [Scrolling to a element inside a scrollable DIV with pure Javascript](https://stackoverflow.com/questions/27980084/scrolling-to-a-element-inside-a-scrollable-div-with-pure-javascript) – CBroe Apr 13 '18 at 07:29
  • I know, I tried elmnt.scrollTop and this had the same effect. I will continue looking. – Sprose Apr 13 '18 at 07:30

1 Answers1

0

I have no come up with a solution in JQuery.

var hasScrolled = false;

function isInViewport() {
    if (!hasScrolled) {
        var elem = $('#prices_table');
        if (elem !== undefined) {
            var elementTop = elem.offset().top;
            var elemBottom = elementTop + elem.outerHeight();
            var viewportTop = $(window).scrollTop();
            var viewportBottom = viewportTop + $(window).height();

            // return elemBottom > viewportTop && elemTop < viewportBottom;
            if (elemBottom > viewportTop && elementTop < viewportBottom) {
                var activeRow = $('#prices_table').find('tr td.active');
                var containerToScroll = $('#prices_table').find('tbody');
                var tdHeight = activeRow.outerHeight();
                if (activeRow) {
                    if (activeRow[0] !== undefined{
                 $(containerToScroll).scrollTop(($('#prices_table').find('tr td.active').offset().top - $('#prices_table').find('tbody').offset().top) - (tdHeight * 2));
                          hasScrolled = true;
                      }
                 }
            }
        }
    }
}


$(window).scroll(function() {
    isInViewport('#prices_table');
});

I have a few variables to check before actually scrolling, as sometimes the element is in the correct place on load, and once it has scrolled once I don't want it to move.

  • On Scroll I now check if element is in view.
  • I then check if element has previously scrolled, if it hasn't then I will continue.
  • I set element, if it doesn't exist then I don't continue.
  • I do some calculations to check the difference the scroll needs to move, if there is no difference I don't continue.
  • I then do my calculation and update variable hasScrolled to true so this never fires again.

Bit of a longer approach than I was looking for but it works a treat.

Sprose
  • 1,255
  • 1
  • 16
  • 20