28

私は MVC のプロジェクトに取り組んでおり、それについて学ぶことを楽しんでいます。いくつかの成長痛がありますが、一度理解すれば悪くありません。WebForms の世界で非常に単純なことの 1 つは、ページのスクロール位置を維持することです。あなたがすることは、MaintainScrollPositionOnPostback プロパティを true に設定することだけです。ただし、MVC では、ポストバックを使用していないため、これは機能しません。これを処理する標準的な方法は何ですか?

編集: Ajaxは受け入れられますが、AJAXなしでどうやってそれを行うのかも疑問に思っていました.

4

12 に答える 12

8

MaintainScrollPositionOnPostback が機能する方法は、__SCROLLPOSITIONX と __SCROLLPOSITIONY の 1 組の非表示フィールドがあることです。

ポストバックでは、これらを設定します。

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-04T17:49:40.357 に答える
6

実際、これを処理する標準的な方法はありません。これは、ポストバックモデルをサポートするためのMicrosoftのハックでした。すべてのコントロールがポストバックを実行し、ユーザーが常にページの上部にプッシュバックされるため、これが必要でした。

MVCでの使用をお勧めするのは、AJAXを使用してほとんどの投稿をサーバーに戻すことです。ページを再レンダリングする必要がないように、フォーカスは移動されません。jQueryはAJAXを本当に簡単にし、次のようなデフォルトのフォームもあります

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

これはあなたのために物事のAJAX側の世話をします。

于 2009-01-27T18:20:02.427 に答える
4

WebForms と Richard Gadsden によって提供された回答からインスピレーションを得て、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 を使用しているため、完全に機能しており、クロス ブラウザ セーフである必要があります。提供されたコードは一目瞭然だと思いますが、何が起こっているかについてより詳細な説明を喜んで提供します。

于 2011-07-13T19:57:01.057 に答える
3

私自身の回避策はViewData、バックナビゲーションに表示する必要のある領域を知るための情報と、ページのカーソルを配置するための小さなJavaScriptを使用することです。

ビューでは、次のような要素があります。

<h3 id="tasks">
    Contained tasks
</h3>

そして、ページを再配置するためのjavascript:

<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て、ビューページから再配置する必要のある要素を決定できます。

それが役に立てば幸い。

于 2009-01-27T18:14:59.630 に答える
3

タグに名前属性を使用しました。JavaScriptは使用されていません。

戻りたいページには、名前属性を持つ<a>タグがありました(例:<a name="testname">)。

使用済みタグ<ahref="<%:Request.UrlReferrer%>#testname">戻る</a>"から戻ったページ(表示)。Request.UrlReferrerは前のページに移動するために使用されます。#testnameはページをスクロールします「testname」という名前でタグ付けする位置。

于 2011-01-18T06:42:35.860 に答える
2
<%
   if(!ViewData.ModelState.IsValid)
   {
%>
   window.location.hash = 'Error';
<%
   }
%>

 <a name="Error"></a>
于 2010-06-15T04:36:30.820 に答える
1

これは、FF4とIE9でのみテストしたシンプルで純粋なJavascriptソリューションです。

このソリューションは#anchor、ページの標準タグにフォールバックすることで適切に機能を低下させる必要があるという考え方です。私がやっていることは、それらの#anchorタグをその場でX座標とY座標に置き換え、ロード時に、クエリ文字列からそれらの値を読み取り、そこでスクロールするだけです。これが何らかの理由で失敗した場合でも、ブラウザはその#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);
    });
});
}

いくつかのヘルパーメソッド:

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];
}

これは私のニーズに合っていますが、より一般的/再利用可能である可能性があります-誰かがこれを改善してくれることを嬉しく思います... :-)

于 2011-05-08T23:10:41.427 に答える
0

これを行うための非常に良くない方法は、Cookieを使用することです。

他のページを処理するMVCで1つのページを使用する場合は、「scrolltop」と呼ばれるCookie(存在しない場合)を作成するすべてのページをロードするコードスニペットを使用できます。ユーザーがこれらのイベントをキャッチするか、scrollTop値を監視することにより、ユーザーが上下にスクロールしたときにjavascriptがこのCookieを自動的に更新するようにする方法があります。

新しいページでは、保存された位置をロードし、0ミリ秒でビューをスクロールさせる必要があります(Mootoolsまたは任意のAjaxスクリプトを使用すると、これが可能になります)。ユーザーは正確に元の場所に移動します。

aspについてはよくわからないので、現在のy位置に固定する方法が存在するかどうかはわかりません。Javascriptは速くて簡単な方法です。すべての要素をアンカーして他のページにアンカーを投稿した場合は、HTM1のアンカーがオプションになる可能性があります。

于 2009-01-27T18:25:04.197 に答える
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 値を取得します。最後に、ページは Web フォームのように動作し、すべてがそのまま残ります。

于 2013-12-31T20:08:21.763 に答える
-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

于 2016-06-30T09:37:09.207 に答える