[英]How do I get an element to scroll into view, using jQuery?
我有一个HTML文档,其中包含使用<ul><li><img...
的网格格式图像。 浏览器窗口同时具有垂直和水平滚动。
问题:单击图像<img>
,如何使整个文档滚动到我刚刚单击的图像为top:20px; left:20px
top:20px; left:20px
?
我在这里浏览过类似的文章...虽然我对JavaScript还是很陌生,但想了解如何自己实现。
所有主流浏览器都支持一个名为scrollIntoView
的DOM方法,该方法会将元素与视口的顶部/左侧(或尽可能靠近)对齐。
$("#myImage")[0].scrollIntoView();
在受支持的浏览器上,您可以提供以下选项:
$("#myImage")[0].scrollIntoView({
behavior: "smooth", // or "auto" or "instant"
block: "start" // or "end"
});
或者,如果所有元素都有唯一的ID,则只需更改location
对象的hash
属性以支持后退/前进按钮:
$(document).delegate("img", function (e) {
if (e.target.id)
window.location.hash = e.target.id;
});
之后,只需将scrollTop
/ scrollLeft
属性调整为-20:
document.body.scrollLeft -= 20;
document.body.scrollTop -= 20;
由于您想知道它是如何工作的,因此我将逐步解释它。
首先,您要将一个函数绑定为图像的单击处理程序:
$('#someImage').click(function () {
// Code to do scrolling happens here
});
这会将点击处理程序应用于id="someImage"
的图像。 如果要对所有图像执行此操作,请将'#someImage'
替换为'img'
。
现在查看实际的滚动代码:
获取图像偏移量(相对于文档):
var offset = $(this).offset(); // Contains .top and .left
从top
和left
减去20:
offset.left -= 20; offset.top -= 20;
现在设置<body>
和<html>
CSS滚动属性和滚动属性:
$('html, body').animate({ scrollTop: offset.top, scrollLeft: offset.left });
我见过的最简单的解决方案
var offset = $("#target-element").offset();
$('html, body').animate({
scrollTop: offset.top,
scrollLeft: offset.left
}, 1000);
看一下jQuery.scrollTo插件。 这是一个演示 。
这个插件有很多选项,超出了本机scrollIntoView所能提供的范围。 例如,您可以将滚动设置为平滑,然后在滚动完成时设置回调。
您还可以查看所有标记为“ scroll”的JQuery插件 。
有一些方法可以将元素直接滚动到视图中,但是如果要滚动到元素的相对点,则必须手动进行操作:
在点击处理程序内,获取元素相对于文档的位置,减去20
并使用window.scrollTo
:
var pos = $(this).offset();
var top = pos.top - 20;
var left = pos.left - 20;
window.scrollTo((left < 0 ? 0 : left), (top < 0 ? 0 : top));
这是一个快速的jQuery插件,可以很好地映射内置的浏览器功能:
$.fn.ensureVisible = function () { $(this).each(function () { $(this)[0].scrollIntoView(); }); };
...
$('.my-elements').ensureVisible();
经过反复试验,我想出了这个功能,也可以与iframe一起使用。
function bringElIntoView(el) {
var elOffset = el.offset();
var $window = $(window);
var windowScrollBottom = $window.scrollTop() + $window.height();
var scrollToPos = -1;
if (elOffset.top < $window.scrollTop()) // element is hidden in the top
scrollToPos = elOffset.top;
else if (elOffset.top + el.height() > windowScrollBottom) // element is hidden in the bottom
scrollToPos = $window.scrollTop() + (elOffset.top + el.height() - windowScrollBottom);
if (scrollToPos !== -1)
$('html, body').animate({ scrollTop: scrollToPos });
}
只是一个小费。 仅适用于Firefox
我的UI在拇指栏中有一个垂直滚动的拇指列表,目的是使当前拇指恰好位于拇指栏的中央。 我从批准的答案开始,但是发现有一些调整可以使当前的拇指真正居中。 希望这对其他人有帮助。
标记:
<ul id='thumbbar'>
<li id='thumbbar-123'></li>
<li id='thumbbar-124'></li>
<li id='thumbbar-125'></li>
</ul>
jQuery的:
// scroll the current thumb bar thumb into view
heightbar = $('#thumbbar').height();
heightthumb = $('#thumbbar-' + pageid).height();
offsetbar = $('#thumbbar').scrollTop();
$('#thumbbar').animate({
scrollTop: offsetthumb.top - heightbar / 2 - offsetbar - 20
});
简单的2个步骤即可向下滚动到结尾或底部。
步骤1:获取可滚动(会话)div的完整高度。
步骤2:使用在步骤1中获得的值在该scrollable(会话)div上应用scrollTop。
var fullHeight = $('#conversation')[0].scrollHeight;
$('#conversation').scrollTop(fullHeight);
以上步骤必须应用于对话div上的每个追加。
在尝试找到一种能够处理所有情况的解决方案(用于动画滚动的选项,对象滚动到视图中时在其周围进行填充,甚至在诸如iframe等晦涩的情况下也可以使用)之后,我最终结束了为此编写自己的解决方案。 由于当许多其他解决方案失败时它似乎可以工作,所以我想分享一下:
function scrollIntoViewIfNeeded($target, options) {
var options = options ? options : {},
$win = $($target[0].ownerDocument.defaultView), //get the window object of the $target, don't use "window" because the element could possibly be in a different iframe than the one calling the function
$container = options.$container ? options.$container : $win,
padding = options.padding ? options.padding : 20,
elemTop = $target.offset().top,
elemHeight = $target.outerHeight(),
containerTop = $container.scrollTop(),
//Everything past this point is used only to get the container's visible height, which is needed to do this accurately
containerHeight = $container.outerHeight(),
winTop = $win.scrollTop(),
winBot = winTop + $win.height(),
containerVisibleTop = containerTop < winTop ? winTop : containerTop,
containerVisibleBottom = containerTop + containerHeight > winBot ? winBot : containerTop + containerHeight,
containerVisibleHeight = containerVisibleBottom - containerVisibleTop;
if (elemTop < containerTop) {
//scroll up
if (options.instant) {
$container.scrollTop(elemTop - padding);
} else {
$container.animate({scrollTop: elemTop - padding}, options.animationOptions);
}
} else if (elemTop + elemHeight > containerTop + containerVisibleHeight) {
//scroll down
if (options.instant) {
$container.scrollTop(elemTop + elemHeight - containerVisibleHeight + padding);
} else {
$container.animate({scrollTop: elemTop + elemHeight - containerVisibleHeight + padding}, options.animationOptions);
}
}
}
$target
是一个jQuery对象,其中包含您希望在需要时滚动到视图中的对象。
options
(可选)可以包含在对象中传递的以下选项:
options.$container
一个jQuery对象,指向$ target的包含元素(换句话说,带有滚动条的dom中的元素)。 默认为包含$ target元素的窗口,并且足够聪明以选择iframe窗口。 请记住在属性名称中包含$。
options.padding
滚动到视图中时对象上方或下方添加的像素填充。 这样,它就不能紧贴窗口边缘。 默认为20
options.instant
如果设置为true,将不使用jQuery animate,并且滚动条将立即弹出到正确的位置。 默认为false。
options.animationOptions
您希望传递给jQuery animate函数的任何jQuery选项(请参阅http://api.jquery.com/animate/ )。 这样,您可以更改动画的持续时间,或者在滚动完成后执行回调函数。 仅当options.instant
设置为false时,此方法才有效。 如果您需要即时动画但带有回调,请设置options.animationOptions.duration = 0
而不是使用options.instant = true
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.