我正在從事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