如何使用 jQuery 让元素滚动到视图中?
Posted
技术标签:
【中文标题】如何使用 jQuery 让元素滚动到视图中?【英文标题】:How do I get an element to scroll into view, using jQuery? 【发布时间】:2011-06-20 13:38:07 【问题描述】:我有一个使用<ul><li><img...
的带有网格格式图像的html 文档。浏览器窗口具有垂直和水平滚动。
问题:
当我单击图像<img>
时,如何让整个文档滚动到我刚刚单击的图像为top:20px; left:20px
的位置?
我在这里浏览过类似的帖子...虽然我对 javascript 还很陌生,但我想了解自己是如何实现这一点的。
【问题讨论】:
重复:How to scroll to an element in jQuery? 【参考方案1】:有一个名为 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;
【讨论】:
谢谢! 5 其他 SO 文章,你完美地钉了它。我的用例是引导对话框中的一个容器,需要滚动到视图中。 注意:$("#myImage")[0].scrollIntoView(false);
将对齐窗口底部的元素。
注意:“平滑”行为并未得到广泛支持,scrollIntoView
对于没有某种动画的用户来说可能是一种令人困惑的体验。
@JohnHenckel:这是不正确的,即使 IE 5.5 也有带有布尔参数的 scrollIntoView
。我稍后会尝试为 caniuse.com 发送拉取请求。
注意:使用 Chrome,我无法将 <td>
元素滚动到视图中,而是必须滚动它们的父元素 (<tr>
) 并且它起作用了。【参考方案2】:
既然你想知道它是如何工作的,那我就一步步解释。
首先你要绑定一个函数作为图片的点击处理程序:
$('#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>
的scroll-top 和scroll-left CSS 属性设置动画:
$('html, body').animate(
scrollTop: offset.top,
scrollLeft: offset.left
);
【讨论】:
这仅适用于简单的布局。当元素嵌套在多个溢出容器中时,它并不能像 W3C.scrollIntoView
方法那样处理所有情况。
为什么要重新发明***? Element.scrollIntoView()
:developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView
@Serge 因为它是一个尚未在所有浏览器中实现的工作草案
@JohnSmith 请仔细阅读我发布的链接,“浏览器兼容性”部分,你会看到没有浏览器不支持scrollIntoView
@Serge 对不起,我没有意识到,还有 scrollIntoViewOption (这是一个不够广泛的支持)。我想这已经足够了。【参考方案3】:
我见过的最简单的解决方案
var offset = $("#target-element").offset();
$('html, body').animate(
scrollTop: offset.top,
scrollLeft: offset.left
, 1000);
Tutorial Here
【讨论】:
冒着让它变得不那么简单的风险,我编辑了它以支持水平滚动。【参考方案4】:有一些方法可以将元素直接滚动到视图中,但是如果你想滚动到一个元素的相对点,你必须手动完成:
在点击处理程序内部,获取元素相对于文档的位置,减去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));
【讨论】:
【参考方案5】:看看jQuery.scrollTo 插件。这是demo。
这个插件有很多超出native scrollIntoView 为您提供的选项。例如,您可以将滚动设置为平滑,然后设置滚动结束时的回调。
你也可以看看all the JQuery plugins tagged with "scroll"。
【讨论】:
在我的情况下,我在每个浏览器中都获得了不同的偏移量/位置,这个插件帮助我修复了它!谢谢!【参考方案6】:这是一个快速的 jQuery 插件,可以很好地映射内置的浏览器功能:
$.fn.ensureVisible = function () $(this).each(function () $(this)[0].scrollIntoView(); ); ;
...
$('.my-elements').ensureVisible();
【讨论】:
【参考方案7】:经过反复试验,我想出了这个功能,也适用于 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 );
【讨论】:
【参考方案8】:我的 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
);
【讨论】:
我认为你需要添加:offsetthumb = $('#thumbbar-' + pageid).offset();并将对象替换为:scrollTop: offsetthumb.top - heightbar / 2 - heightthumb / 2 + offsetbar【参考方案9】:只是一个提示。仅适用于火狐
Element.scrollIntoView();
【讨论】:
这适用于所有带有布尔参数或根本没有参数的浏览器。仅较少支持更高级的对象参数。 根据developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView,浏览器普遍缺乏对此的支持 现在只支持 Opera Mini 已经足够好了:caniuse.com/#search=scrollIntoView 有许多非常轻量级的 polyfills。【参考方案10】:向下滚动到末尾或底部的简单 2 个步骤。
Step1:获取可滚动(对话)div的全高。
第 2 步:使用该值在该可滚动(对话)div 上应用 scrollTop 在step1中获得。
var fullHeight = $('#conversation')[0].scrollHeight;
$('#conversation').scrollTop(fullHeight);
对话 div 上的每个附加都必须应用上述步骤。
【讨论】:
【参考方案11】:在尝试找到一种可以处理各种情况的解决方案(用于为滚动设置动画的选项、在对象滚动到视图中后在对象周围填充、即使在 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
。
【讨论】:
以上是关于如何使用 jQuery 让元素滚动到视图中?的主要内容,如果未能解决你的问题,请参考以下文章