使用jQuery滚动到一个元素

我有这个input元素:

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

然后我有一些其他元素,比如其他标签的�标签,等等…

当用户单击<input id="#subject">时,页面应该滚动到页面的最后一个元素,并且应该使用漂亮的动画(它应该是一个滚动到底部而不是顶部)来完成。

页面的最后一项是submit按钮,其中#submit

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

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

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

3030959 次浏览

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

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

我从文章平滑滚动到没有jQuery插件的元素中获得了代码。我在下面的示例中对其进行了测试。

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

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

选项:

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

偏移顶:定义滚动目标上方额外行间距的数字。

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

缓解:一个字符串,指示使用哪个缓和函数进行转换。

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

使用这个简单的脚本

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

将使排序,如果在url中找到哈希标签,则scrollTo动画到ID。如果未找到哈希标签,则忽略脚本。

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

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

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

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

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

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

例如:

$("#button").click(function() {$('html, body').animate({scrollTop: parseInt($("#elementtoScrollToID").offset().top)}, 2000);});
$('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);

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

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

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>

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

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

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

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

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

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

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

感谢特里西亚球指出这一点!

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

$(function() {// Generic selector to be used anywhere$(".js-scroll-to").click(function(e) {
// Get the href dynamicallyvar 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>

var scrollTo = function($parent, $element) {var topDiff = $element.position().top - $parent.position().top;
$parent.animate({scrollTop : topDiff}, 100);};

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

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

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

糟糕的用户体验。

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

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

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

要处理这些问题(和一堆其他人),您可以使用我的插件jQuery.scrollable。然后调用变成

$( window ).scrollTo( targetPosition );

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

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

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

即使在html元素上设置了边框,这也有效。

我编写了一个通用函数,可以滚动到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);};

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

页面的最后一项是带有#提交的提交按钮

$('#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>

非常简单易用的自定义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);
// RUNjQuery(document).ready(function($) {$().animateScroll();});
// IN HTML EXAMPLE// RUN ONCLICK ON OBJECT WITH ATTRIBUTE SCROLL=".SELECTOR"// <a scroll="#product">Click To Scroll</a>

不管怎样,这就是我如何设法为可以在DIV中滚动的一般元素实现这种行为的方式。在我们的例子中,我们不滚动整个主体,而是在更大的布局中滚动带有overflow: 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();

使用这个解决方案,您不需要任何插件,除了将脚本放在关闭</body>标签之前之外,还有无需安装

$("a[href^='#']").on("click", function(e) {$("html, body").animate({scrollTop: $($(this).attr("href")).offset().top}, 1000);return false;});
if ($(window.location.hash).length > 1) {$("html, body").animate({scrollTop: $(window.location.hash).offset().top}, 1000);}

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

每当您单击带有href哈希(例如#top)的a链接时,我们会滚动到它。

##编辑2020

如果你想要一个纯JavaScript解决方案:你也许可以使用类似的东西:

var _scrollToElement = function (selector) {try {document.querySelector(selector).scrollIntoView({ behavior: 'smooth' });} catch (e) {console.warn(e);}}
var _scrollToHashesInHrefs = function () {document.querySelectorAll("a[href^='#']").forEach(function (el) {el.addEventListener('click', function (e) {_scrollToElement(el.getAttribute('href'));return false;})})if (window.location.hash) {_scrollToElement(window.location.hash);}}
_scrollToHashesInHrefs();

我设置了一个模块滚动元素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).toplet containerOffsetTop = getElementOffset(containerElement).toplet scrollTarget = targetOffsetTop + ( containerElement.scrollTop - containerOffsetTop)scrollTarget += offsetscroll(containerElement, scrollTarget, duration)}
export const scrollWindowToElement = function(targetElement, duration, offset) {if (duration == null) { duration = 1000 }if (offset == null) { offset = 0 }
let scrollTarget = getElementOffset(targetElement).topscrollTarget += offsetscrollWindow(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.documentElementlet box = element.getBoundingClientRect()let top = box.top + window.pageYOffset - de.clientToplet left = box.left + window.pageXOffset - de.clientLeftreturn { top: top, left: left }}

$('html, body').animate(...)不适用于iPhone,Android,Chrome或Safari浏览器。

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

$('#cot nen t')。动画(…)

这是我最终得到的:

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>

动画:

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

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

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

实现页面滚动到目标div id的简单方法

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

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

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

这对我有效:

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

这在没有jQuery的情况下是可以实现的:

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

2019年更新答案:

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

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>

这是我做事的方式。

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>

文档

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>

您只需要:

$("selector").get(0).scrollTo(0, 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");