jQuery 中如何将一个元素滚动到可视视图中?

我有一个HTML文档的图像在网格格式使用

  • 。浏览器窗口有垂直&水平滚动。

    问题: 当我点击图像时,我如何让整个文档滚动到我刚刚点击的图像是top:20px; left:20px的位置

    我在这里浏览过类似的帖子……虽然我对JavaScript很陌生,想了解这是如何为自己实现的。

278268 次浏览

有一个名为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;

看看jQuery.scrollTo插件。这是一个演示

这个插件有很多超出本机scrollIntoView提供给你的选项。例如,您可以将滚动设置为平滑,然后设置滚动结束时的回调。

你也可以看看所有JQuery插件都带有“scroll”标签

既然你想知道它是如何工作的,我将一步一步地解释它。

首先,你需要绑定一个函数作为图像的点击处理程序:

$('#someImage').click(function () {
// Code to do scrolling happens here
});

将click处理程序应用于带有id="someImage"的图像。如果你想对所有图像这样做,用'img'替换'#someImage'

现在来看实际的滚动代码:

  1. 获取图像偏移量(相对于文档):

    var offset = $(this).offset(); // Contains .top and .left
    
  2. Subtract 20 from top and left:

    offset.left -= 20;
    offset.top -= 20;
    
  3. Now animate the scroll-top and scroll-left CSS properties of <body> and <html>:

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

有一些方法可以直接将元素滚动到视图中,但如果你想从一个元素滚动到一个相对的点,你必须手动执行:

在click处理程序中,获取元素相对于文档的位置,减去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));
我的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
});

下面是一个快速的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

Element.scrollIntoView()

我见过的最简单的解决方法

var offset = $("#target-element").offset();
$('html, body').animate({
scrollTop: offset.top,
scrollLeft: offset.left
}, 1000);

教程

简单的2步向下滚动到结束或底部。

Step1:获得可滚动(对话)div的完整高度。

Step2:在可滚动(会话)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动画将不被使用,滚动将立即弹出到正确的位置。默认为false。

options.animationOptions -任何你想传递给jQuery动画函数的jQuery选项(参见http://api.jquery.com/animate/)。有了它,您可以改变动画的持续时间,或者在滚动完成时执行回调函数。这仅在options.instant设置为false时有效。如果你需要一个带有回调的即时动画,设置options.animationOptions.duration = 0而不是使用options.instant = true