[Special Summer Sale] 40% OFF All Magento 2 Themes

Cart

Scroll to an element with jQuery

  • This topic is empty.
Viewing 15 posts - 1 through 15 (of 31 total)
  • Author
    Posts
  • #9741
    diegop.
    Participant

    I have this input element:

      <input type="text" class="textfield" value="" id="subject" name="subject">
    

    Then I have some other elements, like other tag’s & <textarea> tag’s, etc…

    When the user clicks on the <input id="#subject">, the page should scroll to the page’s last element, and it should do so with a nice animation (It should be a scroll to bottom and not to top).

    The last item of the page is a submit button with #submit:

    <input type="submit" class="submit" id="submit" name="submit" value="Ok, Done.">
    

    The animation should not be too fast and should be fluid.

    I am running the latest jQuery version. I prefer to not install any plugin but to use the default jQuery features to achieve this.

    #9770
    warface
    Participant

    Using this simple script

    if($(window.location.hash).length > 0){
            $('html, body').animate({ scrollTop: $(window.location.hash).offset().top}, 1000);
    }
    

    Would make in sort that if a hash tag is found in the url, the scrollTo animate to the ID. If not hash tag found, then ignore the script.

    #9767
    tejasvi-hegde
    Participant

    The solution by Steve and Peter works very well.

    But in some cases, you may have to convert the value to an integer. Strangely, the returned value from $("...").offset().top is sometimes in float.
    Use: parseInt($("....").offset().top)

    For example:

    $("#button").click(function() {
        $('html, body').animate({
            scrollTop: parseInt($("#elementtoScrollToID").offset().top)
        }, 2000);
    });
    
    #9751
    user669677
    Participant
    $('html, body').animate({scrollTop: 
      Math.min( 
        $(to).offset().top-margintop, //margintop is the margin above the target
        $('body')[0].scrollHeight-$('body').height()) //if the target is at the bottom
    }, 2000);
    
    #9752
    roman-shamritskiy
    Participant

    To show the full element (if it’s possible with the current window size):

    var element       = $("#some_element");
    var elementHeight = element.height();
    var windowHeight  = $(window).height();
    
    var offset = Math.min(elementHeight, windowHeight) + element.offset().top;
    $('html, body').animate({ scrollTop: offset }, 500);
    
    #9769
    davidcondrey
    Participant
    jQuery(document).ready(function($) {
      $('a[href^="#"]').bind('click.smoothscroll',function (e) {
        e.preventDefault();
        var target = this.hash,
            $target = $(target);
    
        $('html, body').stop().animate( {
          'scrollTop': $target.offset().top-40
        }, 900, 'swing', function () {
          window.location.hash = target;
        } );
      } );
    } );
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    
    
    <ul role="tablist">
      <li class="active" id="p1"><a href="#pane1" role="tab">Section 1</a></li>
      <li id="p2"><a href="#pane2" role="tab">Section 2</a></li>
      <li id="p3"><a href="#pane3" role="tab">Section 3</a></li>
    </ul>
    
    <div id="pane1"></div>
    <div id="pane2"></div>
    <div id="pane3"></div>
    #9766
    rezgar-cadro
    Participant

    A compact version of “animate” solution.

    $.fn.scrollTo = function (speed) {
        if (typeof(speed) === 'undefined')
            speed = 1000;
    
        $('html, body').animate({
            scrollTop: parseInt($(this).offset().top)
        }, speed);
    };
    

    Basic usage: $('#your_element').scrollTo();

    #9764
    benjamin-oakes
    Participant

    If you are only handling scrolling to an input element, you can use focus(). For example, if you wanted to scroll to the first visible input:

    $(':input:visible').first().focus();
    

    Or the first visible input in an container with class .error:

    $('.error :input:visible').first().focus();
    

    Thanks to Tricia Ball for pointing this out!

    #9756
    vascogaspar
    Participant

    This is my approach abstracting the ID’s and href’s, using a generic class selector

    $(function() {
      // Generic selector to be used anywhere
      $(".js-scroll-to").click(function(e) {
    
        // Get the href dynamically
        var destination = $(this).attr('href');
    
        // Prevent href=“#” link from changing the URL hash (optional)
        e.preventDefault();
    
        // Animate scroll to destination
        $('html, body').animate({
          scrollTop: $(destination).offset().top
        }, 500);
      });
    });
    <!-- example of a fixed nav menu -->
    <ul class="nav">
      <li>
        <a href="#section-1" class="nav-item js-scroll-to">Item 1</a>
      </li>
      <li>
        <a href="#section-2" class="nav-item js-scroll-to">Item 2</a>
      </li>
      <li>
        <a href="#section-3" class="nav-item js-scroll-to">Item 3</a>
      </li>
    </ul>
    #9753
    kayz1
    Participant
    var scrollTo = function($parent, $element) {
        var topDiff = $element.position().top - $parent.position().top;
    
        $parent.animate({
            scrollTop : topDiff
        }, 100);
    };
    
    #9758
    hashchange
    Participant

    In most cases, it would be best to use a plugin. Seriously. I’m going to tout mine here. Of course there are others, too. But please check if they really avoid the pitfalls for which you’d want a plugin in the first place – not all of them do.

    I have written about the reasons for using a plugin elsewhere. In a nutshell, the one liner underpinning most answers here

    $('html, body').animate( { scrollTop: $target.offset().top }, duration );
    

    is bad UX.

    • The animation doesn’t respond to user actions. It carries on even if the user clicks, taps, or tries to scroll.

    • If the starting point of the animation is close to the target element, the animation is painfully slow.

    • If the target element is placed near the bottom of the page, it can’t be scrolled to the top of the window. The scroll animation stops abruptly then, in mid motion.

    To handle these issues (and a bunch of others), you can use a plugin of mine, jQuery.scrollable. The call then becomes

    $( window ).scrollTo( targetPosition );
    

    and that’s it. Of course, there are more options.

    With regard to the target position, $target.offset().top does the job in most cases. But please be aware that the returned value doesn’t take a border on the html element into account (see this demo). If you need the target position to be accurate under any circumstances, it is better to use

    targetPosition = $( window ).scrollTop() + $target[0].getBoundingClientRect().top;
    

    That works even if a border on the html element is set.

    #9747
    isapir
    Participant

    I wrote a general purpose function that scrolls to either a jQuery object, a CSS selector, or a numeric value.

    Example usage:

    // scroll to "#target-element":
    $.scrollTo("#target-element");
    
    // scroll to 80 pixels above first element with class ".invalid":
    $.scrollTo(".invalid", -80);
    
    // scroll a container with id "#my-container" to 300 pixels from its top:
    $.scrollTo(300, 0, "slow", "#my-container");
    

    The function’s code:

    /**
    * Scrolls the container to the target position minus the offset
    *
    * @param target    - the destination to scroll to, can be a jQuery object
    *                    jQuery selector, or numeric position
    * @param offset    - the offset in pixels from the target position, e.g.
    *                    pass -80 to scroll to 80 pixels above the target
    * @param speed     - the scroll speed in milliseconds, or one of the
    *                    strings "fast" or "slow". default: 500
    * @param container - a jQuery object or selector for the container to
    *                    be scrolled. default: "html, body"
    */
    jQuery.scrollTo = function (target, offset, speed, container) {
    
        if (isNaN(target)) {
    
            if (!(target instanceof jQuery))
                target = $(target);
    
            target = parseInt(target.offset().top);
        }
    
        container = container || "html, body";
        if (!(container instanceof jQuery))
            container = $(container);
    
        speed = speed || 500;
        offset = offset || 0;
    
        container.animate({
            scrollTop: target + offset
        }, speed);
    };
    
    #9748
    khaled.k
    Participant

    When the user clicks on that input with #subject, the page should
    scroll to the last element of the page with a nice animation. It
    should be a scroll to bottom and not to top.

    The last item of the page is a submit button with #submit

    $('#subject').click(function()
    {
        $('#submit').focus();
        $('#subject').focus();
    });
    

    This will first scroll down to #submit then restore the cursor back to the input that was clicked, which mimics a scroll down, and works on most browsers. It also doesn’t require jQuery as it can be written in pure JavaScript.

    Can this fashion of using focus function mimic animation in a better way, through chaining focus calls. I haven’t tested this theory, but it would look something like this:

    <style>
      #F > *
      {
        width: 100%;
      }
    </style>
    
    <form id="F" >
      <div id="child_1"> .. </div>
      <div id="child_2"> .. </div>
      ..
      <div id="child_K"> .. </div>
    </form>
    
    <script>
      $('#child_N').click(function()
      {
        $('#child_N').focus();
        $('#child_N+1').focus();
        ..
        $('#child_K').focus();
    
        $('#child_N').focus();
      });
    </script>
    
    #9757
    devwl
    Participant

    Very simple and easy to use custom jQuery plugin. Just add the attribute scroll= to your clickable element and set its value to the selector you want to scroll to.

    Like so: <a scroll="#product">Click me</a>. It can be used on any element.

    (function($){
        $.fn.animateScroll = function(){
            console.log($('[scroll]'));
            $('[scroll]').click(function(){
                selector = $($(this).attr('scroll'));
                console.log(selector);
                console.log(selector.offset().top);
                $('html body').animate(
                    {scrollTop: (selector.offset().top)}, //- $(window).scrollTop()
                    1000
                );
            });
        }
    })(jQuery);
    
    // RUN
    jQuery(document).ready(function($) {
        $().animateScroll();
    });
    
    // IN HTML EXAMPLE
    // RUN ONCLICK ON OBJECT WITH ATTRIBUTE SCROLL=".SELECTOR"
    // <a scroll="#product">Click To Scroll</a>
    
    #9743
    martinh_kentico
    Participant

    For what it’s worth, this is how I managed to achieve such behavior for a general element which can be inside a DIV with scrolling. In our case we don’t scroll the full body, but just particular elements with overflow: auto; within a larger layout.

    It creates a fake input of the height of the target element, and then puts a focus to it, and the browser will take care about the rest no matter how deep within the scrollable hierarchy you are. Works like a charm.

    var $scrollTo = $('#someId'),
    inputElem = $('<input type="text"></input>');
    
    $scrollTo.prepend(inputElem);
    inputElem.css({
      position: 'absolute',
      width: '1px',
      height: $scrollTo.height()
    });
    inputElem.focus();
    inputElem.remove();
    
Viewing 15 posts - 1 through 15 (of 31 total)
  • You must be logged in to reply to this topic.