How do I get an element to scroll into view, using jQuery?

后端 未结 11 1346
夕颜
夕颜 2020-11-28 19:31

I have an HTML document with images in a grid format using

  • . The browser window has both vertical & horizontal scrolling.

相关标签:
11条回答
  • 2020-11-28 20:07

    After trying to find a solution that handled every circumstance (options for animating the scroll, padding around the object once it scrolls into view, works even in obscure circumstances such as in an iframe), I finally ended up writing my own solution to this. Since it seems to work when many other solutions failed, I thought I'd share it:

    function scrollIntoViewIfNeeded($target, options) {
    
        var options = options ? options : {},
        $win = $($target[0].ownerDocument.defaultView), //get the window object of the $target, don't use "window" because the element could possibly be in a different iframe than the one calling the function
        $container = options.$container ? options.$container : $win,        
        padding = options.padding ? options.padding : 20,
        elemTop = $target.offset().top,
        elemHeight = $target.outerHeight(),
        containerTop = $container.scrollTop(),
        //Everything past this point is used only to get the container's visible height, which is needed to do this accurately
        containerHeight = $container.outerHeight(),
        winTop = $win.scrollTop(),
        winBot = winTop + $win.height(),
        containerVisibleTop = containerTop < winTop ? winTop : containerTop,
        containerVisibleBottom = containerTop + containerHeight > winBot ? winBot : containerTop + containerHeight,
        containerVisibleHeight = containerVisibleBottom - containerVisibleTop;
    
        if (elemTop < containerTop) {
            //scroll up
            if (options.instant) {
                $container.scrollTop(elemTop - padding);
            } else {
                $container.animate({scrollTop: elemTop - padding}, options.animationOptions);
            }
        } else if (elemTop + elemHeight > containerTop + containerVisibleHeight) {
            //scroll down
            if (options.instant) {
                $container.scrollTop(elemTop + elemHeight - containerVisibleHeight + padding);
            } else {
                $container.animate({scrollTop: elemTop + elemHeight - containerVisibleHeight + padding}, options.animationOptions);
            }
        }
    }
    

    $target is a jQuery object containing the object you wish to scroll into view if needed.

    options (optional) can contain the following options passed in an object:

    options.$container - a jQuery object pointing to the containing element of $target (in other words, the element in the dom with the scrollbars). Defaults to the window that contains the $target element and is smart enough to select an iframe window. Remember to include the $ in the property name.

    options.padding - the padding in pixels to add above or below the object when it is scrolled into view. This way it is not right against the edge of the window. Defaults to 20.

    options.instant - if set to true, jQuery animate will not be used and the scroll will instantly pop to the correct location. Defaults to false.

    options.animationOptions - any jQuery options you wish to pass to the jQuery animate function (see http://api.jquery.com/animate/). With this, you can change the duration of the animation or have a callback function executed when the scrolling is complete. This only works if options.instant is set to false. If you need to have an instant animation but with a callback, set options.animationOptions.duration = 0 instead of using options.instant = true.

    0 讨论(0)
  • 2020-11-28 20:09

    There's a DOM method called scrollIntoView, which is supported by all major browsers, that will align an element with the top/left of the viewport (or as close as possible).

    $("#myImage")[0].scrollIntoView();
    

    On supported browsers, you can provide options:

    $("#myImage")[0].scrollIntoView({
        behavior: "smooth", // or "auto" or "instant"
        block: "start" // or "end"
    });
    

    Alternatively, if all the elements have unique IDs, you can just change the hash property of the location object for back/forward button support:

    $(document).delegate("img", function (e) {
        if (e.target.id)
            window.location.hash = e.target.id;
    });
    

    After that, just adjust the scrollTop/scrollLeft properties by -20:

    document.body.scrollLeft -= 20;
    document.body.scrollTop -= 20;
    
    0 讨论(0)
  • 2020-11-28 20:11

    Since you want to know how it works, I'll explain it step-by-step.

    First you want to bind a function as the image's click handler:

    $('#someImage').click(function () {
        // Code to do scrolling happens here
    });
    

    That will apply the click handler to an image with id="someImage". If you want to do this to all images, replace '#someImage' with 'img'.

    Now for the actual scrolling code:

    1. Get the image offsets (relative to the document):

      var offset = $(this).offset(); // Contains .top and .left
      
    2. Subtract 20 from top and left:

      offset.left -= 20;
      offset.top -= 20;
      
    3. Now animate the scroll-top and scroll-left CSS properties of <body> and <html>:

      $('html, body').animate({
          scrollTop: offset.top,
          scrollLeft: offset.left
      });
      
    0 讨论(0)
  • 2020-11-28 20:12

    Simplest solution I have seen

    var offset = $("#target-element").offset();
    $('html, body').animate({
        scrollTop: offset.top,
        scrollLeft: offset.left
    }, 1000);
    

    Tutorial Here

    0 讨论(0)
  • 2020-11-28 20:16

    My UI has a vertical scrolling list of thumbs within a thumbbar The goal was to make the current thumb right in the center of the thumbbar. I started from the approved answer, but found that there were a few tweaks to truly center the current thumb. hope this helps someone else.

    markup:

    <ul id='thumbbar'>
        <li id='thumbbar-123'></li>
        <li id='thumbbar-124'></li>
        <li id='thumbbar-125'></li>
    </ul>
    

    jquery:

    // scroll the current thumb bar thumb into view
    heightbar   = $('#thumbbar').height();
    heightthumb = $('#thumbbar-' + pageid).height();
    offsetbar   = $('#thumbbar').scrollTop();
    
    
    $('#thumbbar').animate({
        scrollTop: offsetthumb.top - heightbar / 2 - offsetbar - 20
    });
    
    0 讨论(0)
  • Simple 2 steps for scrolling down to end or bottom.

    Step1: get the full height of scrollable(conversation) div.

    Step2: apply scrollTop on that scrollable(conversation) div using the value obtained in step1.

    var fullHeight = $('#conversation')[0].scrollHeight;
    
    $('#conversation').scrollTop(fullHeight);
    

    Above steps must be applied for every append on the conversation div.

    0 讨论(0)
提交回复
热议问题