仅在不在视图中时滚动到元素 - jQuery
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了仅在不在视图中时滚动到元素 - jQuery相关的知识,希望对你有一定的参考价值。
我知道有几次这样的变化;我已经浏览了一段时间,但要么我做错了,要么我找不到我需要的东西。
我有一个嵌套注释的结构,几乎和Facebook Comments plugin一样,每当点击reply
时,一个带有textarea的小表单和一个按钮出现在注释的底部。
同样,行为与Facebook Comments plugin相同,我想在滚动新添加textarea到视图时实现相同的目标。
我已经尝试了scrollTo插件,它工作顺利但是,即使我手动滚动到页面的最底部,滚动动画将始终重置滚动位置并从顶部开始。
为了记录,这就是我调用scrollTo的方式:
$.scrollTo($('#addReply_1'), 800);
其中addReply_1
是包含该形式的div
。我已经大步滚动到表单本身和textarea
。结果相同。
有没有办法滚动到元素只有它尚未可见?
我已经尝试过很多解决方案,就像Scroll to an element using jQuery一样,但似乎没有任何表现符合要求;甚至Scroll to a particular element w/ jQuery或Check if element is visible after scrolling也表现出相同的“跳跃”行为。
更新:在线演示以显示行为
我上传了一个html演示页面,显示了我抱怨的行为:http://www.wouldbebetter.com/demo/comment-demo.htm
只需滚动到页面底部,然后单击任何Reply
链接即可查看我所指的“跳跃”滚动。
请注意,此演示使用@Robert Koritnik的答案的scrollintoview
插件,但如果我使用ScrollTo,则行为是相同的。
是的,只有当jQuery插件不在可滚动祖先的可见边界内时,它才会滚动到元素。我写过一个完全符合你的要求。与scrollTo()
相比,您可能会发现它更容易使用,因为您只需要提供您想要看到的元素。
我可以在这里复制粘贴代码,但由于我不时添加一些附加内容,最好将您链接到blog post,在那里您将找到与编程滚动和最新插件代码相关的所有细节。程序化滚动可能会让用户和整个用户界面体验分散注意力,因此我认为这将是一个有趣的阅读。
用法
插件非常简单易用:
$("#ElementToScrollIntoView").scrollintoview();
插件会自动找到最近的可滚动祖先并相应地滚动它(如果需要的话)。您可以使用此插件的一些其他设置,这就是它们的样子:
scrollintoview: function (options)
/// <summary>Scrolls the first element in the set into view by scrolling its closest scrollable parent.</summary>
/// <param name="options" type="Object">Additional options that can configure scrolling:
/// duration (default: "fast") - jQuery animation speed (can be a duration string or number of milliseconds)
/// direction (default: "both") - select possible scrollings ("vertical" or "y", "horizontal" or "x", "both")
/// complete (default: none) - a function to call when scrolling completes (called in context of the DOM element being scrolled)
/// </param>
/// <return type="jQuery">Returns the same jQuery set that this function was run on.</return>
我在我的Sharepoint 2010网站上使用这个插件,在我提供长表格数据的页面上。每当我向这个表添加一个新项目(行)时,我还会滚动到这个新记录并突出显示它,这样用户就可以立即看到新记录。
Sharepoint也是我决定不手动提供可滚动元素而是以编程方式查找它的原因。 Sharepoint使用admin costumizable主页,这意味着我不知道哪个元素在运行时可以滚动。但我确实知道我想看哪个元素。因此这个插件。与支持各种不同场景的scrollTo()
插件相比,它也相当简化。大多数时候,开发人员倾向于只使用一个(或者数量非常有限)。
补充意见
默认链接点击处理预防
使用我的插件仍然会使它成为问题,因为添加这些回复框时会有一些闪烁。问题是您的链接点击实际执行。您应该阻止这种情况,以使您的页面顺利运行:
- 或者通过以下两种方式之一在链接上设置点击事件:
<a href="javascript:void AddReplyForm(44); return false;">Reply</a>
要么<a href="#" onclick="void AddReplyForm(44); return false;">Reply</a>
- 更好的方法是在文档就绪上运行:
$(function() $("a").click(function(evt) evt.preventDefault(); ); );
主要思想是阻止浏览器处理链接点击。因为这会使浏览器查找页内锚点,因为它找不到,所以它会自动滚动到顶部。然后你告诉它滚动到你的元素。
重复的ID
创建回复表单时,添加新元素和新元素,但它们都具有相同的ID。您应该避免这样做或使用其他方法。您可以通过向BindClick()
函数提供元素来完全删除ID。主回复生成函数也可以看起来像这样(这个函数的编写方式完全消除了元素ID的需要):
function AddReplyForm(topCommentID)
var el = $(addReplyForm).appendTo('#comment_' + topCommentID + ' .right');
BindClick(el); // mind this !! you provide the element to remove
el.scrollintoview();
有同样的问题......在回顾几个答案之后,这就是我想出来做的事情......没有拉下另一个插件。
function scrollIntoViewIfNeeded($target)
if ($target.position())
if ($target.position().top < jQuery(window).scrollTop())
//scroll up
$('html,body').animate(scrollTop: $target.position().top);
else if ($target.position().top + $target.height() >
$(window).scrollTop() + (
window.innerHeight || document.documentElement.clientHeight
))
//scroll down
$('html,body').animate(scrollTop: $target.position().top -
(window.innerHeight || document.documentElement.clientHeight)
+ $target.height() + 15
);
最后一行的“15”只是额外填充 - 您可能需要调整它,或将其添加到向上滚动行。
编辑:将window.innerHeight
更改为(window.innerHeight || document.documentElement.clientHeight)
,IE <8支持
所有现代浏览器都支持这一点。访问:http://caniuse.com/#search=scrollIntoView
function scrollIntoViewIfNeeded(target)
var rect = target.getBoundingClientRect();
if (rect.bottom > window.innerHeight)
target.scrollIntoView(false);
if (rect.top < 0)
target.scrollIntoView();
更新
目标必须是元素。如果你使用jQuery调用这样的函数:
scrollIntoViewIfNeeded($(".target")[0]);
确保元素在容器内的视图中:
let rectElem = elem.getBoundingClientRect(), rectContainer=container.getBoundingClientRect();
if (rectElem.bottom > rectContainer.bottom) elem.scrollIntoView(false);
if (rectElem.top < rectContainer.top) elem.scrollIntoView();
我稍微修改了@iandisme的答案并将其作为一个小的jquery插件包装起来:
(function ($)
'use strict';
$.fn.scrollToSimple = function ($target)
var $container = this.first(); // Only scrolls the first matched container
var pos = $target.position(), height = $target.outerHeight();
var containerScrollTop = $container.scrollTop(), containerHeight = $container.height();
var top = pos.top + containerScrollTop; // position.top is relative to the scrollTop of the containing element
var paddingPx = containerHeight * 0.15; // padding keeps the target from being butted up against the top / bottom of the container after scroll
if (top < containerScrollTop) // scroll up
$container.scrollTop(top - paddingPx);
else if (top + height > containerScrollTop + containerHeight) // scroll down
$container.scrollTop(top + height - containerHeight + paddingPx);
;
)(jQuery);
我删除了对.animate的调用,因为我正在寻找即时滚动。我还添加了滚动任何(可滚动)容器的功能,而不仅仅是窗口。用法示例:
// scroll the window so #target is visible
$(window).scrollToSimple( $("#target") );
// scroll the scrollable element #container so that #target is visible
$("#container").scrollToSimple( $("#target") );
我不知道我是否理解你想要的东西,但看看是不是这样,接近或者如果我完全迷失了:
<!DOCTYPE html>
<html>
<head>
<title>Scroll To Reply</title>
<meta charset="utf-8" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function()
var $contextarea = $('#contextform textarea');
$('a.reply').live('click',function()
$(this).closest('p').css('margin-top':'300px;');
$('#contextform').appendTo($(this).closest('p'));
$('#contextform').slideDown(1000);//.css('display':'block');
$(this).closest('p').attr('id','scrolltome');
$('html,body').animate(slideDown: $('#scrolltome').offset().top, 2000);
);
$('.sendreply').live('click',function()
if($contextarea.val() == null || $contextarea.val() == '')
alert('textarea is empty!');
else
$('#contextform').slideUp(800);
);
// $('button').click(function()
// $('html,body').animate(scrollTop: $('#body').offset().top, 2000);//scrolls to the top
// );
);
</script>
<style type="text/css">
body
font-size:25px;
font-family: 'Arimo', Arial, sans-serif;
#contextform
display:none;
width:500px;
height: 150px;
background: #0489B7;
padding: 5px
#contextform textarea
width: 490px;
height: 90px;
</style>
</head>
<body id="body">
<h1>Scroll to reply</h1&g以上是关于仅在不在视图中时滚动到元素 - jQuery的主要内容,如果未能解决你的问题,请参考以下文章