关于javascript:jquery滚动到元素

jQuery scroll to element

我有一个input元素:

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

然后我还有一些其他元素,比如其他文本输入、文本区域等。

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

页面的最后一项是带#submitsubmit按钮:

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

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

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


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

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

我从文章中获得了代码,它可以顺利地滚动到一个没有jquery插件的元素。我已经在下面的例子中对它进行了测试。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<html>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js">
   
        $(document).ready(function (){
            $("#click").click(function (){
                $('html, body').animate({
                    scrollTop: $("#div1").offset().top
                }, 2000);
            });
        });
   
   
        Test
   
    <br/>
   
        Test 2
   
    <button id="click">Click me</button>
</html>


jQuery .scrollTo() Method

jquery.scrollto():视图-演示,API,源代码

我编写这个轻量级插件是为了让页面/元素滚动更容易。它很灵活,可以在其中传递目标元素或指定值。也许这可能是jquery下一次正式发布的一部分,您认为呢?

实例用法:

1
2
3
4
5
$('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

选项:

滚动目标:表示所需滚动位置的元素、字符串或数字。

偏移量:在滚动目标上定义额外间距的数字。

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

宽松:指示用于过渡的宽松函数的字符串。

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


如果您对平滑滚动效果不太感兴趣,只对滚动到某个特定元素感兴趣,那么就不需要使用jquery函数。Javascript为您提供了案例:

https://developer.mozilla.org/en-us/docs/web/api/element.scrollintoview

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

使用.get(0)是因为我们想要检索javascript的dom元素,而不是jquery的dom元素。


使用这个简单的脚本

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

如果在URL中找到散列标记,滚动到ID的动画中。如果没有找到散列标记,则忽略该脚本。


1
2
3
4
5
6
7
8
9
10
11
12
13
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;
    } );
  } );
} );
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">


<ul role="tablist">
  <li class="active" id="p1">Section 1
</li>

  <li id="p2">Section 2
</li>

  <li id="p3">Section 3
</li>


</ul>


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

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

例如:

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

"动画"解决方案的紧凑版本。

1
2
3
4
5
6
7
8
$.fn.scrollTo = function (speed) {
    if (typeof(speed) === 'undefined')
        speed = 1000;

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

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


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

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

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

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

感谢特里西娅·鲍尔指出了这一点!


使用此解决方案,您不需要任何插件,并且除了在关闭标记之前放置脚本之外,不需要任何设置。

1
2
3
4
5
6
7
8
9
10
11
12
$("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);
}

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

当你点击一个带有href散列的a链接时,比如#top,我们滚动到它。


在大多数情况下,最好使用插件。说真的。我要在这里兜售我的。当然还有其他的。但是请检查他们是否真的避免了你首先想要一个插件的陷阱——不是所有的陷阱都能做到。

我已经写了在其他地方使用插件的原因。简言之,这一行支撑了大多数答案

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

是坏的UX。

  • 动画不响应用户操作。即使用户单击、轻击或试图滚动,它也会继续进行。

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

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

要处理这些问题(以及其他一些问题),您可以使用我的插件jquery.scrollable。然后呼叫变成

1
$( window ).scrollTo( targetPosition );

就是这样。当然,还有更多的选择。

至于目标位置,在大多数情况下,由$target.offset().top负责。但请注意,返回值没有考虑到html元素上的边界(参见本演示)。如果在任何情况下都需要目标位置准确,最好使用

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

即使在html元素上设置了边界,也可以实现这一点。


我知道没有jquery的方法:

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

动画:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
// slide to top of the page
$('.up').click(function () {
    $("html, body").animate({
        scrollTop: 0
    }, 600);
    return false;
});

// slide page to anchor
$('.menutop b').click(function(){
    //event.preventDefault();
    $('html, body').animate({
        scrollTop: $( $(this).attr('href') ).offset().top
    }, 600);
    return false;
});

// Scroll to class, div
$("#button").click(function() {
    $('html, body').animate({
        scrollTop: $("#target-element").offset().top
    }, 1000);
});

// div background animate
$(window).scroll(function () {

    var x = $(this).scrollTop();

    // freezze div background
    $('.banner0').css('background-position', '0px ' + x +'px');

    // from left to right
    $('.banner0').css('background-position', x+'px ' +'0px');

    // from right to left
    $('.banner0').css('background-position', -x+'px ' +'0px');

    // from bottom to top
    $('#skills').css('background-position', '0px ' + -x + 'px');

    // move background from top to bottom
    $('.skills1').css('background-position', '0% ' + parseInt(-x / 1) + 'px' + ', 0% ' + parseInt(-x / 1) + 'px, center top');

    // Show hide mtop menu  
    if ( x > 100 ) {
    $(".menu" ).addClass( 'menushow' );
    $(".menu" ).fadeIn("slow");
    $(".menu" ).animate({opacity: 0.75}, 500);
    } else {
    $(".menu" ).removeClass( 'menushow' );
    $(".menu" ).animate({opacity: 1}, 500);
    }

});

// progres bar animation simple
$('.bar1').each(function(i) {
  var width = $(this).data('width');  
  $(this).animate({'width' : width + '%' }, 900, function(){
    // Animation complete
  });  
});

实现页面滚动到目标DIV ID的简单方法

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

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

像这样:Click me。它可以用于任何元素。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
(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"
// Click To Scroll


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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$(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);
  });
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<!-- example of a fixed nav menu -->
<ul class="nav">
 
<li>

    Item 1
 
</li>

 
<li>

    Item 2
 
</li>

 
<li>

    Item 3
 
</li>


</ul>


如果要在溢出容器内滚动(而不是上面回答的$('html, body')),也要使用绝对定位,可以这样做:

1
2
3
4
5
6
7
var elem = $('#myElement'),
    container = $('#myScrollableContainer'),
    pos = elem.position().top + container.scrollTop() - container.position().top;

container.animate({
  scrollTop: pos
}

在iPhone、Android Chrome Safari浏览器上,$('html, body').animate(...)不适合我。

我必须以页面的根内容元素为目标。

$('#cotnent').animate(...)

这就是我的结局

1
2
3
4
5
6
7
8
9
10
if (navigator.userAgent.match(/(iPod|iPhone|iPad|Android)/)) {          
    $('#content').animate({
    scrollTop: $("#elementtoScrollToID").offset().top
   }, 'slow');
}
else{
    $('html, body').animate({
    scrollTop: $("#elementtoScrollToID").offset().top
    }, 'slow');
}

所有与"内容"分区连接的正文内容

1
2
3
4
5
6
7
8
<html>
....
<body>

....

</body>
</html>


1
2
3
4
5
6
7
var scrollTo = function($parent, $element) {
    var topDiff = $element.position().top - $parent.position().top;

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

这是Atharva的答案,来自:https://developer.mozilla.org/en-us/docs/web/api/element.scrollintoview。只想添加如果您的文档在iframe中,您可以选择父框架中的元素滚动到视图中:

1
 $('#element-in-parent-frame', window.parent.document).get(0).scrollIntoView();


1
2
3
4
5
$('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);

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

1
2
3
4
5
6
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);

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

1
2
3
4
5
$('#subject').click(function()
{
    $('#submit').focus();
    $('#subject').focus();
});

这将首先向下滚动到#submit,然后将光标还原回单击的输入,该输入模拟向下滚动,并在大多数浏览器上工作。它也不需要jquery,因为它可以用纯JavaScript编写。

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<style>
  #F > *
  {
    width: 100%;
  }
</style>

<form id="F">
   ..
   ..
  ..
   ..
</form>


  $('#child_N').click(function()
  {
    $('#child_N').focus();
    $('#child_N+1').focus();
    ..
    $('#child_K').focus();

    $('#child_N').focus();
  });

值得一提的是,这就是我如何设法为一般元素实现这种行为的方法,该元素可以在带有滚动的DIV中。在我们的例子中,我们不滚动整个正文,只滚动带有溢出的特定元素:auto;在更大的布局中。

它创建了一个目标元素高度的假输入,然后将焦点放在它上面,不管您在可滚动层次结构中的深度有多深,浏览器都会关注其他元素。很有魅力。

1
2
3
4
5
6
7
8
9
10
11
var $scrollTo = $('#someId'),
inputElem = $('<input type="text"></input>');

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

我设置了一个模块滚动元素npm install scroll-element。工作原理如下:

1
2
3
4
5
6
7
8
9
10
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帖子的帮助下编写:

  • 不带jquery的元素顶部偏移量

  • 不带jquery的Scrolltop动画

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
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 }
}


截至2019年的最新答复:

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

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

示例用法:

1
2
3
4
5
6
7
8
// 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");

函数代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
/**
* 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);
};

1
2
3
4
5
6
7
8
9
10
11
12
13
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;
    } );
  } );
} );
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">


<ul role="tablist">
  <li class="active" id="p1">Section 1
</li>

  <li id="p2">Section 2
</li>

  <li id="p3">Section 3
</li>


</ul>


这对我很有用:

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