jQuery滚动到元素

时间:2011-07-13 09:49:45

标签: javascript jquery

我有input元素:

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

然后我有一些其他元素,比如其他文本输入,textareas等。

当用户使用input点击#subject时,页面应滚动到页面的最后一个元素,并带有一个漂亮的动画。它应该是一个滚动到底部而不是顶部。

该页面的最后一项是带submit的{​​{1}}按钮:

#submit

动画不应该太快,应该是流畅的。

我正在运行最新的jQuery版本。我更喜欢不安装任何插件,而是使用默认的jQuery功能来实现这一点。

32 个答案:

答案 0 :(得分:3746)

假设您有一个ID为button的按钮,请尝试以下示例:

$("#button").click(function() {
    $([document.documentElement, document.body]).animate({
        scrollTop: $("#elementtoScrollToID").offset().top
    }, 2000);
});

我从文章 Smoothly scroll to an element without a jQuery plugin 中获取了代码。我在下面的例子中对它进行了测试。

<html>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script>
    <script>
        $(document).ready(function (){
            $("#click").click(function (){
                $('html, body').animate({
                    scrollTop: $("#div1").offset().top
                }, 2000);
            });
        });
    </script>
    <div id="div1" style="height: 1000px; width 100px">
        Test
    </div>
    <br/>
    <div id="div2" style="height: 1000px; width 100px">
        Test 2
    </div>
    <button id="click">Click me</button>
</html>

答案 1 :(得分:488)

jQuery .scrollTo() Method

jQuery .scrollTo(): View - Demo, API, Source

我编写了这个轻量级插件,使页面/元素滚动变得更加容易。它可以灵活地传递目标元素或指定值。也许这可能是jQuery下一次正式发布的一部分,您怎么看?


示例用法:

$('body').scrollTo('#target'); // Scroll screen to target element

$('body').scrollTo(500); // Scroll screen 500 pixels down

$('#scrollable').scrollTo(100); // Scroll individual element 100 pixels down

选项:

scrollTarget :表示所需滚动位置的元素,字符串或数字。

offsetTop :一个数字,用于定义滚动目标上方的额外间距。

持续时间:确定动画运行时间的字符串或数字。

缓动:一个字符串,指示用于转换的缓动函数。

完成:动画完成后调用的函数。

答案 2 :(得分:316)

如果您对平滑滚动效果不太感兴趣并且只想滚动到特定元素,则不需要一些jQuery函数。 Javascript已涵盖您的案例:

https://developer.mozilla.org/en-US/docs/Web/API/element.scrollIntoView

所以你需要做的就是:$("selector").get(0).scrollIntoView();

使用

.get(0)是因为我们想要检索JavaScript的DOM元素而不是JQuery的DOM元素。

答案 3 :(得分:38)

使用这个简单的脚本

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

如果在url中找到了一个hash标签,那么scrollTo会对ID进行动画处理。如果没有找到哈希标记,则忽略该脚本。

答案 4 :(得分:31)

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>

答案 5 :(得分:20)

史蒂夫和彼得的解决方案非常有效。

但在某些情况下,您可能必须将值转换为整数。奇怪的是,$("...").offset().top的返回值有时为float 使用:parseInt($("....").offset().top)

例如:

$("#button").click(function() {
    $('html, body').animate({
        scrollTop: parseInt($("#elementtoScrollToID").offset().top)
    }, 2000);
});

答案 6 :(得分:16)

“animate”解决方案的紧凑版本。

$.fn.scrollTo = function (speed) {
    if (typeof(speed) === 'undefined')
        speed = 1000;

    $('html, body').animate({
        scrollTop: parseInt($(this).offset().top)
    }, speed);
};

基本用法:$('#your_element').scrollTo();

答案 7 :(得分:15)

使用this solution您不需要任何插件,除了在结束$("a[href^='#']").on("click", function(e) { e.preventDefault(); $("html, body").animate({ scrollTop: $($(this).attr("href")).offset().top }, 1000); }); if ($(window.location.hash).length > 1) { $("html, body").animate({ scrollTop: $(window.location.hash).offset().top }, 1000); } 之前放置脚本之外, 无需设置 标签

a

加载时,如果地址中有哈希,我们滚动到它。

并且 - 每当您点击带有href哈希的#top链接时, {{1}},我们滚动到它。

答案 8 :(得分:15)

如果您只处理滚动到输入元素,则可以使用focus()。例如,如果要滚动到第一个可见输入:

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

或者具有类.error的容器中的第一个可见输入:

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

感谢Tricia Ball指出这一点!

答案 9 :(得分:7)

在大多数情况下,最好使用插件。认真。我要去tout mine here。当然还有其他人。但请检查一下他们是否真的避免了你想要插件的陷阱 - 而不是所有这些都是。

我已经写过使用插件elsewhere的原因。简而言之,这里的一个衬垫支撑了大多数答案

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

是糟糕的用户体验。

  • 动画不响应用户操作。即使用户点击,点击或尝试滚动,它也会继续。

  • 如果动画的起点接近目标元素,则动画速度非常慢。

  • 如果目标元素位于页面底部附近,则无法滚动到窗口顶部。滚动动画在中间运动时突然停止。

要处理这些问题(以及bunch of others),您可以使用我的插件jQuery.scrollable。然后呼叫变为

$( window ).scrollTo( targetPosition );

就是这样。当然,有more options

关于目标位置,$target.offset().top在大多数情况下完成工作。但请注意,返回的值不会考虑html元素上的边框(see this demo)。如果您在任何情况下都需要目标位置准确,最好使用

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

即使设置了html元素上的边框,也能正常工作。

答案 10 :(得分:7)

我知道没有jQuery的方法:

document.getElementById("element-id").scrollIntoView();

答案 11 :(得分:5)

轻松实现页面滚动以定位div id

var targetOffset = $('#divID').offset().top;
$('html, body').animate({scrollTop: targetOffset}, 1000);

答案 12 :(得分:5)

动画:

{{1}}

答案 13 :(得分:5)

非常简单易用的自定义jQuery插件。只需将属性scroll=添加到可点击元素,并将其值设置为要滚动到的选择器即可。

像这样:<a scroll="#product">Click me</a>。它可以用在任何元素上。

(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>

答案 14 :(得分:5)

这是我使用通用类选择器抽象ID和href的方法

&#13;
&#13;
$(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);
  });
});
&#13;
<!-- 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>
&#13;
&#13;
&#13;

答案 15 :(得分:4)

var scrollTo = function($parent, $element) {
    var topDiff = $element.position().top - $parent.position().top;

    $parent.animate({
        scrollTop : topDiff
    }, 100);
};

答案 16 :(得分:4)

这就是我的方法。

document.querySelector('scrollHere').scrollIntoView({ behavior: 'smooth' })

在任何浏览器中均可使用。

它可以很容易地包装成一个函数

function scrollTo(selector) {
    document.querySelector(selector).scrollIntoView({ behavior: 'smooth' })
}

这是一个可行的例子

$(".btn").click(function() {
  document.getElementById("scrollHere").scrollIntoView( {behavior: "smooth" })
})
.btn {margin-bottom: 500px;}
.middle {display: block; margin-bottom: 500px; color: red;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<button class="btn">Scroll down</button>

<h1 class="middle">You see?</h1>

<div id="scrollHere">Arrived at your destination</div>

Docs

答案 17 :(得分:4)

$('html, body').animate(...)不适用于iphone,android chrome safari浏览器。

我必须定位页面的根内容元素。

  

$( '#cotnent')。动画(...)

以下是我的最终结果

if (navigator.userAgent.match(/(iPod|iPhone|iPad|Android)/)) {           
    $('#content').animate({
    scrollTop: $("#elementtoScrollToID").offset().top
   }, 'slow');
}
else{
    $('html, body').animate({
    scrollTop: $("#elementtoScrollToID").offset().top
    }, 'slow');
}

所有正文内容都与#content div相连接

<html>
....
<body>
<div id="content">
....
</div>
</body>
</html>

答案 18 :(得分:4)

如果你想在溢出容器内滚动(而不是上面回答的$('html, body')),同时使用绝对定位,这是可行的方法:

var elem = $('#myElement'),
    container = $('#myScrollableContainer'),
    pos = elem.position().top + container.scrollTop() - container.position().top;

container.animate({
  scrollTop: pos
}

答案 19 :(得分:3)

这是Atharva的回答:https://developer.mozilla.org/en-US/docs/Web/API/element.scrollIntoView。 如果您的文档位于iframe中,只需添加即可,您可以在父框架中选择一个元素以滚动到视图中:

.option_add

答案 20 :(得分:3)

ONELINER

subject.onclick = e=> window.scroll({ top: submit.offsetTop, behavior: 'smooth'});

subject.onclick = e=> window.scroll({top: submit.offsetTop, behavior: 'smooth'});
.box,.foot{display: flex;background:#fdf;padding:500px 0} .foot{padding:250px}
<input type="text" class="textfield" value="click here" id="subject" name="subject">

<div class="box">
  Some content
  <textarea></textarea>
</div>

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

<div class="foot">Some footer</div>

答案 21 :(得分:2)

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>

答案 22 :(得分:2)

对于它的价值,这就是我设法为一般元素实现这种行为的方式,该元素可以在滚动内部进行。在我们的例子中,我们不会滚动整个主体,而只是滚动溢出的特定元素:auto;在更大的布局中。

它会创建目标元素高度的虚假输入,然后将焦点放在其上,无论您在可滚动层次结构中有多深,浏览器都会关注其余部分。像魅力一样。

var $scrollTo = $('#someId'),
inputElem = $('<input type="text"></input>');

$scrollTo.prepend(inputElem);
inputElem.css({
  position: 'absolute',
  width: '1px',
  height: $scrollTo.height()
});
inputElem.focus();
inputElem.remove();

答案 23 :(得分:2)

我设置了一个模块scroll-element npm install scroll-element。它的工作原理如下:

import { scrollToElement, scrollWindowToElement } from 'scroll-element'

/* scroll the window to your target element, duration and offset optional */
let targetElement = document.getElementById('my-item')
scrollWindowToElement(targetElement)

/* scroll the overflow container element to your target element, duration and offset optional */
let containerElement = document.getElementById('my-container')
let targetElement = document.getElementById('my-item')
scrollToElement(containerElement, targetElement)

在以下SO帖子的帮助下撰写:

以下是代码:

export const scrollToElement = function(containerElement, targetElement, duration, offset) {
  if (duration == null) { duration = 1000 }
  if (offset == null) { offset = 0 }

  let targetOffsetTop = getElementOffset(targetElement).top
  let containerOffsetTop = getElementOffset(containerElement).top
  let scrollTarget = targetOffsetTop + ( containerElement.scrollTop - containerOffsetTop)
  scrollTarget += offset
  scroll(containerElement, scrollTarget, duration)
}

export const scrollWindowToElement = function(targetElement, duration, offset) {
  if (duration == null) { duration = 1000 }
  if (offset == null) { offset = 0 }

  let scrollTarget = getElementOffset(targetElement).top
  scrollTarget += offset
  scrollWindow(scrollTarget, duration)
}

function scroll(containerElement, scrollTarget, duration) {
  let scrollStep = scrollTarget / (duration / 15)
  let interval = setInterval(() => {
    if ( containerElement.scrollTop < scrollTarget ) {
      containerElement.scrollTop += scrollStep
    } else {
      clearInterval(interval)
    }
  },15)
}

function scrollWindow(scrollTarget, duration) {
  let scrollStep = scrollTarget / (duration / 15)
  let interval = setInterval(() => {
    if ( window.scrollY < scrollTarget ) {
      window.scrollBy( 0, scrollStep )
    } else {
      clearInterval(interval)
    }
  },15)
}

function getElementOffset(element) {
  let de = document.documentElement
  let box = element.getBoundingClientRect()
  let top = box.top + window.pageYOffset - de.clientTop
  let left = box.left + window.pageXOffset - de.clientLeft
  return { top: top, left: left }
}

答案 24 :(得分:2)

  

当用户使用#subject点击该输入时,页面应该   使用漂亮的动画滚动到页面的最后一个元素。它   应该是滚动到底部而不是顶部。

     

页面的最后一项是#submit

的提交按钮
$('#subject').click(function()
{
    $('#submit').focus();
    $('#subject').focus();
});

这将首先向下滚动到#submit,然后将光标恢复为单击的输入,模拟向下滚动,并适用于大多数浏览器。它也不需要jQuery,因为它可以用纯JavaScript编写。

这种使用focus函数的方式可以通过链接focus调用以更好的方式模仿动画。我没有测试过这个理论,但它看起来像这样:

<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>

答案 25 :(得分:2)

我编写了一个通用函数,可以滚动到jQuery对象,CSS选择器或数值。

使用示例:

// 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");

函数的代码:

/**
* 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);
};

答案 26 :(得分:2)

显示完整元素(如果可以使用当前窗口大小):

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);

答案 27 :(得分:2)

$('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);

答案 28 :(得分:1)

这对我有用:

var targetOffset = $('#elementToScrollTo').offset().top;
$('#DivParent').animate({scrollTop: targetOffset}, 2500);

答案 29 :(得分:1)

截至2019年的最新答案:

$('body').animate({
    scrollTop: $('#subject').offset().top - $('body').offset().top + $('body').scrollTop()
}, 'fast');

答案 30 :(得分:1)

您只需要:

$("selector").get(0).scrollTo(0, 0)

答案 31 :(得分:0)

在找到使代码工作的方法之后,我认为我应该使事情变得清楚一点: 使用方法:

$('html, body').animate({
   scrollTop: $("#div1").offset().top
}, 2000);

您需要位于页面顶部,因为$("#div1").offset().top将针对您滚动到的不同位置返回不同的数字。如果您已经滚动到顶部,则需要指定确切的pageY值(请参见pageY的定义:https://javascript.info/coordinates)。

因此,现在的问题是要计算一个元素的pageY值。以下是滚动容器为主体的示例:

function getPageY(id) {
    let elem = document.getElementById(id);
    let box = elem.getBoundingClientRect();
    var body = document.getElementsByTagName("BODY")[0];
    return box.top + body.scrollTop; // for window scroll: box.top + window.scrollY;
}

即使您滚动到某个位置,上述函数也会返回相同的数字。现在,滚动回该元素:

$("html, body").animate({ scrollTop: getPageY('div1') }, "slow");