如何避免滚动的UpdatePanel上的AutoPostBack? [英] How to avoid UpdatePanel scrolling on AutoPostBack?

查看:146
本文介绍了如何避免滚动的UpdatePanel上的AutoPostBack?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个UpdatePanel内的ASP.NET的FormView。通过设定的AutoPostBack =真对于每个FormView控件中的项目,我自动保存表单。

这意味着用户可以快速连续点击几个元素和几乎同时火了几回发异步。

我的问题是,用户能够保持而异步回发尚未完成向下滚动的形式。浏览器始终滚动回到它是在第一次回传的位置。

Page.MaintainScrollPositionOnPostback设置为False。

我已经试过各种东西在阿贾克斯和jQuery有:


  • 页面加载

  • add_initializeRequest

  • add_endRequest

  • 的document.ready


,但我总是只似乎能够访问滚动y为它是在第一回发

有没有办法回发完成后检索当前滚动Y,这样我就可以停止滚动发生?也许是它可以禁用滚动行为?

谢谢!


更新

由于@chprpipr,我能得到这个工作。这里是我的缩写解决方案:

  VAR FormScrollerProto =功能(){
    VAR我=这;
    this.lastScrollPos = 0;
    VAR myLogger;    this.Setup =功能(记录){
        myLogger =记录仪;
        //绑定功能窗口
        $(窗口).bind(滚动功能(){
            //记录滚动位置
            Me.lastScrollPos = Me.GetScrollTop();
            myLogger.Log(最后的:+ Me.lastScrollPos);
        });
    }    this.ScrollForm =功能(){
        //应用最后滚动位置
        $(窗口).scrollTop(Me.lastScrollPos);
    }    //在pageRequestManager.EndRequest调用此
    this.EndRequestHandler =功能(参数){
        myLogger.Log(args.get_error());
        如果(args.get_error()==未定义){
            Me.ScrollForm();
        }
    }    this.GetScrollTop =功能(){
        返回Me.FilterResults(
                window.pageYOffset? window.pageYOffset:0,
                document.documentElement中? document.documentElement.scrollTop:0,
                document.body的?的document.body.scrollTop:0
            );
    }    this.FilterResults =功能(n_win,n_docel,n_body){
        VAR n_result = n_win? n_win:0;
        如果(n_docel&放大器;及(n_result ||(n_result>!n_docel)))
            n_result = n_docel;
        返回n_body&放大器;&安培; (n_result ||(n_result>!n_body))? n_body:n_result;
    }
}


主页:

  ...略...VAR记录;
    VAR FormScroller;    //挂钩应用程序事件处理程序。
    VAR应用= Sys.Application;    // app.add_load(ApplicationLoad); - 使用页面加载,而不是
    app.add_init(ApplicationInit);
    // app.add_disposing(ApplicationDisposing);
    // app.add_unload(ApplicationUnload);    //应用程序事件处理程序组件开发。
    功能ApplicationInit(发件人){
        变种PRM = Sys.WebForms.PageRequestManager.getInstance();
        如果(!prm.get_isInAsyncPostBack()){
            prm.add_initializeRequest(InitializeRequest);
            prm.add_beginRequest(的BeginRequest);
            prm.add_pageLoading(PageLoading);
            prm.add_pageLoaded(PageLoaded);
            prm.add_endRequest(EndRequest);
        }        //设置组件
        记录器=新LoggerProto();
        logger.Init(真);
        logger.Log(APP ::应用初始化。);        FormScroller =新FormScrollerProto();
    }    功能InitializeRequest(发件人,参数){
        logger.Log(PRM ::初始化异步请求。);
        FormScroller.Setup(记录);
    }...略...功能EndRequest(发件人,参数){
        logger.Log(PRM ::异步请求的结束。);        maintainScroll(发件人,参数);        //显示任何错误
        processErrors(参数);
    }...略...功能maintainScroll(发件人,参数){
        logger.Log(保持+ winScrollTop);
        FormScroller.EndRequestHandler(参数);
    }

我也试过致电EndRequestHandler(不得不删除args.error检查),看它是否滚动时减少闪烁,但事实并非如此。值得注意的是,完美的解决方案将是阻止浏览器试图在所有的滚动 - 现在有一个瞬间的抖动不会在庞大的用户基础应用是可以接受的。

(滚动顶部code是不是我 - 发现它在网络上。)

(下面是客户方的生命周期有帮助的MSDN页面:<一href=\"http://msdn.microsoft.com/en-us/library/bb386417.aspx\">http://msdn.microsoft.com/en-us/library/bb386417.aspx)


更新3月7日:

我刚刚发现了一个非常简单的方法来做到这一点:

 &LT;脚本类型=文/ JavaScript的&GT;变种PRM = Sys.WebForms.PageRequestManager.getInstance();prm.add_beginRequest(的BeginRequest);功能的BeginRequest()
{
    prm._scrollPosition = NULL;
}&LT; / SCRIPT&GT;


解决方案

您可以将绑定注销当前滚动位置的功能,然后在每次重新应用endRequest它。它可能是这样的:

  //总结一切为整洁的缘故
VAR FormHandlerProto =功能(){
    VAR我=这;    this.lastScrollPos = 0;    this.SetupForm =功能(){
        //绑定一个函数形式的滚动容器
        $(#ContainerId)。绑定(滚动功能(){
            //记录滚动位置
            Me.lastScrollPos = $(本).scrollTop();
        });
    }    this.ScrollForm =功能(){
        //应用最后滚动位置
        $(#ContainerId)scrollTop的(Me.lastScrollPos);
    }    this.EndRequestHandler =功能(发件人,参数){
        如果(args.get_error()!=未定义)
            Me.ScrollForm();
        }
    }
}VAR FormHandler =新FormHandlerProto();
FormHandler.Setup(); //这是假设您的滚动容器没有得到回传更新。如果是这样,你要调用它在EndRequestHandler。。Sys.WebForms.PageRequestManager.getInstance()add_endRequest(FormHandler.EndRequestHandler);

I have an ASP.NET FormView within an updatepanel. I'm auto-saving the form by setting AutoPostBack=true for each of the items within the FormView.

This means the user can click a few elements in quick succession and fire off a few async postbacks almost simultaneously.

The issue I have is that the user is able to keep scrolling down the form while the async postbacks are not yet complete. The browser always scrolls back to the position it was in at the first postback.

Page.MaintainScrollPositionOnPostback is set to False.

I've tried all sorts of things in ajax and jquery with:

  • pageLoad
  • add_initializeRequest
  • add_endRequest
  • document.ready
  • etc..

but I always only seem to be able to access the scroll Y as it was on the first postback.

Is there any way to retrieve the current scroll Y when the postback completes, so I can stop the scrolling occurring? Or perhaps is it possible to disable the scrolling behaviour?

Thanks!


Update

Thanks to @chprpipr, I was able to get this to work. Here's my abbreviated solution:

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


Main page:

...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);
    }

I also tried calling the EndRequestHandler (had to remove the args.error check) to see if it reduced flicker when scrolling but it doesn't. It's worth noting that the perfect solution would be to stop the browser trying to scroll at all - right now there is a momentary jitter which would not be acceptable in apps with a large user base.

(The scroll top code is not mine - found it on the web.)

(Here's a helpful MSDN page for the clientside lifecycle: http://msdn.microsoft.com/en-us/library/bb386417.aspx)


Update 7 March:

I just found an extremely simple way to do this:

<script type="text/javascript">

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

prm.add_beginRequest(beginRequest);

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

</script>

解决方案

You could bind a function that logs the current scroll position and then reapplies it after each endRequest. It might go something like this:

// 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);

这篇关于如何避免滚动的UpdatePanel上的AutoPostBack?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆