我有一个嵌套注释的结构,几乎与Facebook Comments plugin相同,并且每当回复被点击时,一个带有textarea和一个按钮的小窗体出现在注释的底部。
再次,行为是相同的Facebook Comments plugin和我想实现相同,当滚动新添加textarea到视图。
我试过scrollTo插件,它的工作流畅,但即使我手动滚动到页面的底部,滚动动画将总是重置滚动位置,从顶部开始。
对于记录,这是我如何调用scrollTo:
$.scrollTo($('#addReply_1'),800);
其中addReply_1是包含表单的div。我已经滚动到窗体本身和textarea。结果相同。
有没有办法滚动到元素,只有它不可见?
我试过很多解决方案提供的SO,像Scroll to an element using jQuery,但没有一个似乎表现得如所希望的;甚至Scroll to a particular element w/ jQuery或jQuery – Check if element is visible after scroling显示相同的“跳跃”行为。
更新:在线演示显示行为
我上传了一个html演示页面,显示我抱怨的行为:http://www.wouldbebetter.com/demo/comment-demo.htm
只需滚动到页面的底部,点击任何回复链接,看到我所指的“跳跃”滚动。
注意,这个演示使用@Robert Koritnik的回答的scrollintoview插件,但是如果我使用例如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使用管理成本的母版页,这意味着我不知道哪些元素将在运行时可滚动。但我知道我想看看哪个元素。因此这个插件。与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(); }