2009-01-27 64 views
22

我正在從事MVC項目的工作,並且很享受這方面的知識。有一些成長的痛苦,但一旦你發現它並不壞。 WebForms世界中一件非常簡單的事情就是保持頁面上的滾動位置。你所做的就是將MaintainScrollPositionOnPostback屬性設置爲true。但是,在MVC中,我不使用回發,所以這不適用於我。處理這個問題的標準方法是什麼?如何在MVC中保持滾動位置?

編輯︰阿賈克斯是可以接受的,但我也想知道你會怎麼做沒有AJAX。

+0

如果您正在使用AJAX和jQuery然後選擇最上面的是你的頁面上的可見元素。說它是一個沒有文字的錨點然後在你的$(document).ready中寫入$('#pageTop')。focus(); – 2013-10-24 11:52:13

回答

8

方式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應該避免回發。

+0

哼!無法編輯好如何編輯這個代碼示例 - 任何人想告訴我我是如何愚蠢? – 2009-02-04 17:52:47

2

我自己的解決方法是使用在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,以確定哪些元素來自您必須重新定位的視圖頁面。

希望它有幫助。

+0

這不會像Web窗體那樣保留確切的位置。 – 2009-01-27 18:18:29

6

實際上沒有處理這個問題的標準方式,這是一個微軟黑客來支持他們的回發模式。他們需要這樣做,因爲每個控件都做了回傳,用戶會不斷被推回到頁面的頂部。

與MVC一起使用的建議是使用AJAX將大部分帖子發回服務器。這樣頁面不必重新渲染,焦點也不會移動。 jQuery使AJAX真的很容易,甚至有默認的形式,如

<% Ajax.BeginForm(...) %> 

這將負責照顧AJAX的一面。

0

一個非常不好的方法是使用cookie。

如果您在處理其他頁面的MVC中使用了一個頁面,您可以爲其加載創建cookie(如果不存在)稱爲「scrolltop」的每個頁面的代碼片段。 當用戶通過捕獲這些事件或觀看scrollTop值而向上或向下滾動時,有許多方法可讓javascript自動更新此cookie。

在新的頁面上,您只需加載保存的位置,並使視圖在0毫秒內滾動(使用Mootools或任何Ajax腳本,這應該是可能的),用戶將確切地位於他們所在的位置。

我不太瞭解asp,所以我不知道是否存在一種方法來錨定當前的y位置。 Javascript是一種快速簡單的方法。如果您將每個元素都錨定並將錨點發布到其他頁面,HTMl中的錨點可能是一個選項。

2
<% 
    if(!ViewData.ModelState.IsValid) 
    { 
%> 
    window.location.hash = 'Error'; 
<% 
    } 
%> 

<a name="Error"></a> 
1

我在標籤中使用了名稱屬性。沒有使用JavaScript。

我想返回的頁面有<a>帶有name屬性的標籤,例如< a name =「testname」>。

頁(圖)我是從舊標籤< A HREF =回來了。 「<%:Request.UrlReferrer%> #testname」 >回</A >」 Request.UrlReferrer用來轉到上一頁。 #testname滾動頁面位置與名稱「測試名」標記。

1

這裏有一個簡單的,純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]; 
} 

這符合我的需求,但可能更通用/可重用 - 我很樂意有人以改善此... :-)

4

以從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來執行滾動操作。我相信所提供的代碼是不言自明的,但我會很樂意提供關於發生了什麼的更詳細的描述,請讓我知道。

+0

謝謝,這個工作對我來說很輕鬆! – Kon 2012-02-01 02:19:05

+0

額外感謝我的來信。我把最後3行放到我的$(document).ready()部分,並且這一切都很好。 – Rocklan 2012-11-19 23:01:10

26

我在JS解決了這個:

$(document).scroll(function(){ 
    localStorage['page'] = document.URL; 
    localStorage['scrollTop'] = $(document).scrollTop(); 
}); 

然後在文件準備:

$(document).ready(function(){ 
    if (localStorage['page'] == document.URL) { 
     $(document).scrollTop(localStorage['scrollTop']); 
    } 
}); 
0

我用.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一樣,一切都保持不變。

-1

@{ 
 

 
} 
 

 
<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

相關問題