提问人:DiegoP. 提问时间:7/13/2011 最后编辑:JΛYDΞVDiegoP. 更新时间:8/15/2023 访问量:3139405
使用 jQuery 滚动到元素
Scroll to an element with jQuery
问:
我有这个元素:input
<input type="text" class="textfield" value="" id="subject" name="subject">
然后我还有一些其他元素,比如其他标签和标签等......<textarea>
当用户单击 时,页面应该滚动到页面的最后一个元素,并且应该有一个漂亮的动画(它应该滚动到底部而不是顶部)。<input id="#subject">
页面的最后一项是一个按钮,其中包含:submit
#submit
<input type="submit" class="submit" id="submit" name="submit" value="Ok, Done.">
动画不应太快,并且应该流畅。
我正在运行最新的jQuery版本。我宁愿不安装任何插件,而是使用默认的jQuery功能来实现这一点。
答:
假设您有一个带有 id 的按钮,请尝试以下示例:button
$("#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(): 视图 - 演示、API、源代码
我编写了这个轻量级插件,以使页面/元素滚动变得更加容易。它可以灵活地传入目标元素或指定值。也许这可能是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:一个数字,用于定义滚动目标上方的额外间距。
duration:一个字符串或数字,用于确定动画的运行时间。
easing:一个字符串,指示用于转换的缓动函数。
complete:动画完成后调用的函数。
评论
scrollTo is not a function
使用这个简单的脚本
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 元素。
更新
现在可以通过动画滚动,传递滚动选项(参见 MDN)。您甚至可以控制块位置。除了Safari之外,它似乎有很大的支持
$("selector").get(0).scrollIntoView({behavior: 'smooth'});
评论
$(selector)[0]
document.getElementById('#elementID').scrollIntoView()
document.getElementById('elementID').scrollIntoView()
史蒂夫和彼得的解决方案效果很好。
但在某些情况下,您可能需要将该值转换为整数。奇怪的是,从 返回的值有时在 中。
用:$("...").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>
评论
jQuery(document).ready(function($) { $(document).on( "click", 'a[href^="#"]', function( e ) { e.preventDefault(); var target = this.hash, $target = $(target); $('html, body').stop().animate({ scrollTop: $target.offset().top - 100}, 1000); }); });
“动画”解决方案的精简版本。
$.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();
感谢 Tricia Ball 指出这一点!
这是我使用泛型类选择器抽象 ID 和 href 的方法
$(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>
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
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 单击该输入时,页面应 滚动到带有漂亮动画的页面的最后一个元素。它 应该是滚动到底部而不是顶部。
页面的最后一项是带有 #submit 的提交按钮
$('#subject').click(function()
{
$('#submit').focus();
$('#subject').focus();
});
这将首先向下滚动,然后将光标恢复到单击的输入,这模仿向下滚动,适用于大多数浏览器。它也不需要jQuery,因为它可以用纯JavaScript编写。#submit
这种使用函数的方式能否通过链接调用以更好的方式模仿动画。我还没有测试过这个理论,但它看起来像这样: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);
// RUN
jQuery(document).ready(function($) {
$().animateScroll();
});
// IN HTML EXAMPLE
// RUN ONCLICK ON OBJECT WITH ATTRIBUTE SCROLL=".SELECTOR"
// <a scroll="#product">Click To Scroll</a>
就其价值而言,这就是我设法为一个可以在滚动的 DIV 内部的一般元素实现这种行为的方式。在我们的例子中,我们不滚动整个身体,而只是滚动带有溢出的特定元素: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);
}
加载时,如果地址中有哈希值,我们会滚动到它。
而且 - 每当您单击带有哈希值的链接时,例如,我们都会滚动到它。a
href
#top
##Edit 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();
我设置了一个模块 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 }
}
$('html, body').animate(...)
在 iPhone、Android、Chrome 或 Safari 浏览器中对我不起作用。
我必须以页面的根内容元素为目标。
$('#content').animate(...)
这是我最终得到的:
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 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
});
});
如果你想在一个溢出容器内滚动(而不是上面回答),同时使用绝对定位,这是这样做的方法:$('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。 只是想添加一下,如果你的文档在iframe中,你可以在父框架中选择一个元素来滚动到视图中:
$('#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>
评论
chrome://flags/#smooth-scrolling
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);
您需要在页面顶部,因为会为您滚动到的不同位置返回不同的数字。如果您已经从顶部滚动出来,则需要指定确切的值(请参阅此处的定义:https://javascript.info/coordinates)。$("#div1").offset().top
pageY
pageY
所以现在的问题是计算一个元素的值。下面是一个示例,如果滚动容器是正文: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");
会解决问题,但会改变你的哈希值。如果您使用 Jquery 选项卡并希望页面滚动到选项卡标题,您可以:
$('#needed_tab').tab('show');
window.location.hash = '#tabs_block';
下一个:在jQuery中添加表行
评论
scrollTo
由于 chrome 插件而被我禁用,不确定是哪个。