12

updatepanel 内に ASP.NET FormView があります。FormView 内の各項目に AutoPostBack=true を設定して、フォームを自動保存しています。

これは、ユーザーがいくつかの要素をすばやく連続してクリックし、いくつかの非同期ポストバックをほぼ同時に起動できることを意味します。

私が抱えている問題は、非同期ポストバックがまだ完了していないときに、ユーザーがフォームを下にスクロールし続けることができることです。ブラウザーは常に、最初のポストバック時の位置にスクロールして戻ります。

Page.MaintainScrollPositionOnPostback が False に設定されています。

私はajaxとjqueryであらゆる種類のことを試しました:

  • ページロード
  • add_initializeRequest
  • add_endRequest
  • ドキュメント準備完了
  • 等..

しかし、最初のポストバックのときと同じように、常にスクロール Y にしかアクセスできないようです。

ポストバックが完了したときに現在のスクロール Y を取得する方法はありますか? または、スクロール動作を無効にすることは可能ですか?

ありがとう!


アップデート

@chprpipr のおかげで、これを機能させることができました。これが私の省略された解決策です:

var FormScrollerProto = function () {
    var Me = this;
    this.lastScrollPos = 0;
    var myLogger;

    this.Setup = function (logger) {
        myLogger = logger;
        // Bind a function to the window
        $(window).bind("scroll", function () {
            // Record the scroll position
            Me.lastScrollPos = Me.GetScrollTop();
            myLogger.Log("last: " + Me.lastScrollPos);
        });
    }

    this.ScrollForm = function () {
        // Apply the last scroll position
        $(window).scrollTop(Me.lastScrollPos);
    }

    // Call this in pageRequestManager.EndRequest
    this.EndRequestHandler = function (args) {
        myLogger.Log(args.get_error());
        if (args.get_error() == undefined) {
            Me.ScrollForm();
        }
    }

    this.GetScrollTop = function () {
        return Me.FilterResults(
                window.pageYOffset ? window.pageYOffset : 0,
                document.documentElement ? document.documentElement.scrollTop : 0,
                document.body ? document.body.scrollTop : 0
            );
    }

    this.FilterResults = function (n_win, n_docel, n_body) {
        var n_result = n_win ? n_win : 0;
        if (n_docel && (!n_result || (n_result > n_docel)))
            n_result = n_docel;
        return n_body && (!n_result || (n_result > n_body)) ? n_body : n_result;
    }
}

メインページ:

...snip...

var logger;
    var FormScroller;

    // Hook up Application event handlers.
    var app = Sys.Application;

    // app.add_load(ApplicationLoad); - use pageLoad instead
    app.add_init(ApplicationInit);
    // app.add_disposing(ApplicationDisposing);
    // app.add_unload(ApplicationUnload);

    // Application event handlers for component developers.
    function ApplicationInit(sender) {
        var prm = Sys.WebForms.PageRequestManager.getInstance();
        if (!prm.get_isInAsyncPostBack()) {
            prm.add_initializeRequest(InitializeRequest);
            prm.add_beginRequest(BeginRequest);
            prm.add_pageLoading(PageLoading);
            prm.add_pageLoaded(PageLoaded);
            prm.add_endRequest(EndRequest);
        }

        // Set up components
        logger = new LoggerProto();
        logger.Init(true);
        logger.Log("APP:: Application init.");

        FormScroller = new FormScrollerProto();
    }

    function InitializeRequest(sender, args) {
        logger.Log("PRM:: Initializing async request.");
        FormScroller.Setup(logger);
    }

...snip...

function EndRequest(sender, args) {
        logger.Log("PRM:: End of async request.");

        maintainScroll(sender, args);

        // Display any errors
        processErrors(args);
    }

...snip...

function maintainScroll(sender, args) {
        logger.Log("maintain: " + winScrollTop);
        FormScroller.EndRequestHandler(args);
    }

また、EndRequestHandler (args.error チェックを削除する必要がありました) を呼び出して、スクロール時のちらつきが減少するかどうかを確認しようとしましたが、そうではありません。完璧な解決策は、ブラウザーがスクロールしようとするのを完全に停止することであることに注意してください。現在、大規模なユーザー ベースのアプリでは許容できない瞬間的なジッターがあります。

(スクロールトップのコードは私のものではありません - ウェブで見つけました。)

(クライアント側のライフサイクルに関する役立つ MSDN ページは次のとおりです: http://msdn.microsoft.com/en-us/library/bb386417.aspx )


3 月 7 日更新:

これを行うための非常に簡単な方法を見つけました:

<script type="text/javascript">

var prm = Sys.WebForms.PageRequestManager.getInstance();

prm.add_beginRequest(beginRequest);

function beginRequest()
{
    prm._scrollPosition = null;
}

</script>
4

2 に答える 2

5

現在のスクロール位置をログに記録し、各endRequestの後にそれを再適用する関数をバインドできます。それは次のようになるかもしれません:

// Wrap everything up for tidiness' sake
var FormHandlerProto = function() {
    var Me = this;

    this.lastScrollPos = 0;

    this.SetupForm = function() {
        // Bind a function to the form's scroll container
        $("#ContainerId").bind("scroll", function() {
            // Record the scroll position
            Me.lastScrollPos = $(this).scrollTop();
        });
    }

    this.ScrollForm = function() {
        // Apply the last scroll position
        $("#ContainerId").scrollTop(Me.lastScrollPos);
    }

    this.EndRequestHandler = function(sender, args) {
        if (args.get_error() != undefined)
            Me.ScrollForm();
        }
    }
}

var FormHandler = new FormHandlerProto();
FormHandler.Setup(); // This assumes your scroll container doesn't get updated on postback.  If it does, you'll want to call it in the EndRequestHandler.

Sys.WebForms.PageRequestManager.getInstance().add_endRequest(FormHandler.EndRequestHandler);
于 2011-03-01T08:10:31.317 に答える
0

Timer コントロールをコンテンツ テンプレート内に配置するだけです。

<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:Timer ID="Timer1" runat="server" Interval="5000" OnTick="Timer1_Tick">
</asp:Timer>
<asp:ImageButton ID="ImageButton1" runat="server" Height="350" Width="700" />
</ContentTemplate>
</asp:UpdatePanel>
于 2018-05-16T14:09:57.697 に答える