我正在从事MVC项目的工作,并且很享受这方面的知识。有一些成长的痛苦,但一旦你发现它并不坏。 WebForms世界中一件非常简单的事情就是保持页面上的滚动位置。你所做的就是将MaintainScrollPositionOnPostback属性设置为true。但是,在MVC中,我不使用回发,所以这不适用于我。处理这个问题的标准方法是什么?如何在MVC中保持滚动位置?
编辑︰阿贾克斯是可以接受的,但我也想知道你会怎么做没有AJAX。
我正在从事MVC项目的工作,并且很享受这方面的知识。有一些成长的痛苦,但一旦你发现它并不坏。 WebForms世界中一件非常简单的事情就是保持页面上的滚动位置。你所做的就是将MaintainScrollPositionOnPostback属性设置为true。但是,在MVC中,我不使用回发,所以这不适用于我。处理这个问题的标准方法是什么?如何在MVC中保持滚动位置?
编辑︰阿贾克斯是可以接受的,但我也想知道你会怎么做没有AJAX。
方式MaintainScrollPositionOnPostback工作原理是,它有一对隐藏字段: __SCROLLPOSITIONX和__SCROLLPOSITIONY
在回发,它集这些,
function WebForm_GetScrollY() {
if (__nonMSDOMBrowser) {
return window.pageYOffset;
}
else {
if (document.documentElement && document.documentElement.scrollTop) {
return document.documentElement.scrollTop;
}
else if (document.body) {
return document.body.scrollTop;
}
}
return 0;
}
function WebForm_SaveScrollPositionSubmit() {
if (__nonMSDOMBrowser) {
theForm.elements['__SCROLLPOSITIONY'].value = window.pageYOffset;
theForm.elements['__SCROLLPOSITIONX'].value = window.pageXOffset;
}
else {
theForm.__SCROLLPOSITIONX.value = WebForm_GetScrollX();
theForm.__SCROLLPOSITIONY.value = WebForm_GetScrollY();
}
if ((typeof(this.oldSubmit) != "undefined") && (this.oldSubmit != null)) {
return this.oldSubmit();
}
return true;
}
然后调用RestoreScrollPosition:
function WebForm_RestoreScrollPosition() {
if (__nonMSDOMBrowser) {
window.scrollTo(theForm.elements['__SCROLLPOSITIONX'].value, theForm.elements['__SCROLLPOSITIONY'].value);
}
else {
window.scrollTo(theForm.__SCROLLPOSITIONX.value, theForm.__SCROLLPOSITIONY.value);
}
if ((typeof(theForm.oldOnLoad) != "undefined") && (theForm.oldOnLoad != null)) {
return theForm.oldOnLoad();
}
return true;
}
但正如大多数人所说,MVC应该避免回发。
哼!无法编辑好如何编辑这个代码示例 - 任何人想告诉我我是如何愚蠢? – 2009-02-04 17:52:47
我自己的解决方法是使用在ViewData
一些信息知道必须在backnavigation显示什么区域,以及一些JavaScript来定位页面的光标:
在视图中,像这样的元素:
<h3 id="tasks">
Contained tasks
</h3>
和JavaScript来repositionate页:
<script type="text/javascript">
addOnLoad(goAnchor);
function goAnchor() {
var paging = <%= //Here you determine (from the ViewData or whatever) if you have to position the element %>;
if (paging == "True") {
window.location.hash = "tasks";
}
</script>
你可以使用一个switch
,以确定哪些元素来自您必须重新定位的视图页面。
希望它有帮助。
这不会像Web窗体那样保留确切的位置。 – 2009-01-27 18:18:29
实际上没有处理这个问题的标准方式,这是一个微软黑客来支持他们的回发模式。他们需要这样做,因为每个控件都做了回传,用户会不断被推回到页面的顶部。
与MVC一起使用的建议是使用AJAX将大部分帖子发回服务器。这样页面不必重新渲染,焦点也不会移动。 jQuery使AJAX真的很容易,甚至有默认的形式,如
<% Ajax.BeginForm(...) %>
这将负责照顾AJAX的一面。
一个非常不好的方法是使用cookie。
如果您在处理其他页面的MVC中使用了一个页面,您可以为其加载创建cookie(如果不存在)称为“scrolltop”的每个页面的代码片段。 当用户通过捕获这些事件或观看scrollTop值而向上或向下滚动时,有许多方法可让javascript自动更新此cookie。
在新的页面上,您只需加载保存的位置,并使视图在0毫秒内滚动(使用Mootools或任何Ajax脚本,这应该是可能的),用户将确切地位于他们所在的位置。
我不太了解asp,所以我不知道是否存在一种方法来锚定当前的y位置。 Javascript是一种快速简单的方法。如果您将每个元素都锚定并将锚点发布到其他页面,HTMl中的锚点可能是一个选项。
<%
if(!ViewData.ModelState.IsValid)
{
%>
window.location.hash = 'Error';
<%
}
%>
<a name="Error"></a>
我在标签中使用了名称属性。没有使用JavaScript。
我想返回的页面有<a>带有name属性的标签,例如< a name =“testname”>。
页(图)我是从旧标签< A HREF =回来了。 “<%:Request.UrlReferrer%> #testname” >回</A >” Request.UrlReferrer用来转到上一页。 #testname滚动页面位置与名称“测试名”标记。
这里有一个简单的,纯JavaScript的解决方案,我在FF4和IE9只测试过
的想法是,这个解决方案应该由优雅降级回到页面上的标准#anchor
标签。我在做什么ing正在用X和Y坐标替换这些#anchor
标签,然后在加载时,我只是从查询字符串中读取这些值并滚动到那里。如果由于某种原因失败,浏览器还是应该定位到#anchor
位置...
标记:
<a href="/somecontroller/someaction/#someanchor">My Link</a>
的jQuery:
$(function() {
// RESTORE SCROLL POSITION
RestoreScrollPosition();
// SAVE SCROLL POSITION
$('a:not(a[href^="http"])').filter('[href$="#someanchor"]').each(function() {
$(this).click(function() {
var href = $(this).attr('href').replace("#someanchor","");
if (href.indexOf('?') == -1) {
href = href + '?x='
} else {
href = href + '&x='
}
href = href + window.pageXOffset;
href = href + '&y=' + window.pageYOffset;
$(this).attr('href', href);
});
});
}
的helper方法:
function RestoreScrollPosition() {
var scrollX = gup('x');
var scrollY = gup('y');
if (scrollX != null && scrollY != null) {
window.scrollTo(scrollX, scrollY);
return true;
}
return false;
}
function gup(name) {
name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]");
var regexS = "[\\?&]" + name + "=([^&#]*)";
var regex = new RegExp(regexS);
var results = regex.exec(window.location.href);
if (results == null)
return "";
else
return results[1];
}
这符合我的需求,但可能更通用/可重用 - 我很乐意有人以改善此... :-)
以从WebForms的灵感,由理查德·加兹登,使用JavaScript和形式收集可能是这个样子的另一种方法提供了答案:
@{
var scrollPositionX = string.Empty;
if(IsPost) {
scrollPositionX = Request.Form["ScrollPositionX"];
}
}
<form action="" method="post">
<input type="hidden" id="ScrollPositionX" name="ScrollPositionX" value="@scrollPositionX" />
<input type="submit" id="Submit" name="Submit" value="Go" />
</form>
$("#Submit").click(function() {
$("#ScrollPositionX").val($(document).scrollTop());
});
$("#ScrollPositionX").each(function() {
var val = parseInt($(this).val(), 10);
if (!isNaN(val))
$(document).scrollTop(val);
});
代码提供的是灵感,并没有任何美化。它可能会以几种不同的方式完成,我想这一切都归结于您如何决定在整个POST中保留文档的scrollTop值。它完全正常工作,并且应该跨浏览器安全,因为我们使用jQuery来执行滚动操作。我相信所提供的代码是不言自明的,但我会很乐意提供关于发生了什么的更详细的描述,请让我知道。
我在JS解决了这个:
$(document).scroll(function(){
localStorage['page'] = document.URL;
localStorage['scrollTop'] = $(document).scrollTop();
});
然后在文件准备:
$(document).ready(function(){
if (localStorage['page'] == document.URL) {
$(document).scrollTop(localStorage['scrollTop']);
}
});
我用.scrollTop如下图所示,很容易的,它甚至在多种形式的作品查看(我有很长的视野,分解成多种形式):
首先把这个属性放在模型里面:
public string scrollTop { get; set; }
并在视图中,形式#1内:
@Html.HiddenFor(m => m.scrollTop, new {@id="ScrollForm1"})
内表#2:
@Html.HiddenFor(m => m.scrollTop, new {@id="ScrollForm2"})
内表#2:
@Html.HiddenFor(m => m.scrollTop, new {@id="ScrollForm3"})
,然后在底部视图:
$(document).ready(function() {
$(document).scrollTop(@Model.scrollTop);
$(document).scroll(function() {
$("#ScrollForm1").val($(document).scrollTop());
$("#ScrollForm2").val($(document).scrollTop());
$("#ScrollForm3").val($(document).scrollTop());
});
});
回滚后,您的滚动位置始终保留,因为@ Html.HiddenFor字段会存储当前滚动并将其传递给模型。然后,当页面出现时,它会从模型中获取scrollTop值。最后你的页面会像webform一样,一切都保持不变。
@{
}
<html>
<head>
<script type="text/javascript">
window.onload = function() {
var div = document.getElementById("dvScroll");
var div_position = document.getElementById("div_position");
var position = parseInt(@Request.Form("div_position"));
if (isNaN(position)) {
position = 0;
}
div.scrollTop = position;
div.onscroll = function() {
div_position.value = div.scrollTop;
};
};
</script>
</head>
<body>
<div id="dvScroll" style="overflow-y: scroll; height: 260px; width: 300px">
1. This is a sample text
<br />
2. This is a sample text
<br />
3. This is a sample text
<br />
4. This is a sample text
<br />
5. This is a sample text
<br />
6. This is a sample text
<br />
7. This is a sample text
<br />
8. This is a sample text
<br />
9. This is a sample text
<br />
10. This is a sample text
<br />
11. This is a sample text
<br />
12. This is a sample text
<br />
13. This is a sample text
<br />
14. This is a sample text
<br />
15. This is a sample text
<br />
16. This is a sample text
<br />
17. This is a sample text
<br />
18. This is a sample text
<br />
19. This is a sample text
<br />
20. This is a sample text
<br />
21. This is a sample text
<br />
22. This is a sample text
<br />
23. This is a sample text
<br />
24. This is a sample text
<br />
25. This is a sample text
<br />
</div>
<hr />
<form method="post">
<input type="hidden" id="div_position" name="div_position" />
<input type="submit" value="Cool" />
</form>
</body>
</html>
您可以用它来保持回发后滚动位置。
来源:http://www.aspsnippets.com/Articles/Maintain-Scroll-Position-of-DIV-on-PostBack-in-ASPNet.aspx
如果您正在使用AJAX和jQuery然后选择最上面的是你的页面上的可见元素。说它是一个没有文字的锚点然后在你的$(document).ready中写入$('#pageTop')。focus(); – 2013-10-24 11:52:13