【问题标题】:Maintain scroll position in listboxes in updatepanels, NOT the page在更新面板的列表框中保持滚动位置,而不是页面
【发布时间】:2009-02-12 20:39:11
【问题描述】:

我在更新面板中有一个列表框。当我向下滚动并选择一个项目时,它会滚动回列表框的顶部。我听说 dom 不会跟踪回发时的滚动位置。有没有人有关于如何解决这个问题的解决方案/示例?

谢谢, 赛软

【问题讨论】:

    标签: c# asp.net listbox


    【解决方案1】:

    您遇到了这个问题,因为当异步请求返回时,UpdatePanel 将滚动的 <select> 元素完全替换为新元素。

    可能的解决方案:

    1. 在提交UpdatePanel之前(通过调用ClientScriptManager.RegisterOnSubmitStatement方法),使用JavaScript将<select>元素的scrollTop属性存储在隐藏的表单元素中(通过调用ClientScriptManager.RegisterOnSubmitStatement方法),然后将其设置在新的@ 987654333@ 当 AJAX 调用返回时。这会很乏味、容易出错,而且可能不太兼容(请参阅here)。

    2. 使用 JavaScript 存储 <select>selectedIndex 属性,并在 AJAX 调用返回时重新选择该项目。如果用户还没有选择任何东西,这显然是行不通的。

    3. Don't use UpdatePanels。试试jQuery + ASP.NET page methods

    【讨论】:

    【解决方案2】:
        var xPos, yPos;
        var prm = Sys.WebForms.PageRequestManager.getInstance();
    
        function BeginRequestHandler(sender, args) {
            if (($get('Panel1')) != null) {
                xPos = $get('Panel1').scrollLeft;
                yPos = $get('Panel1').scrollTop;
            }
        }
    
        function EndRequestHandler(sender, args) {
            if (($get('Panel1')) != null) {
                $get('Panel1').scrollLeft = xPos;
                $get('Panel1').scrollTop = yPos;
            }
        }
        prm.add_beginRequest(BeginRequestHandler);
        prm.add_endRequest(EndRequestHandler);
    
        //Note: "Panel1" Panel or div u want to maintain scroll position
        //Note: This Java Script should be added after Scriptmanager*****
    

    //在没有更新面板的情况下保持面板/Div的滚动位置

        window.onload = function() {
            var strCook = document.cookie;
            if (strCook.indexOf("!~") != 0) {
                var intS = strCook.indexOf("!~");
                var intE = strCook.indexOf("~!");
                var strPos = strCook.substring(intS + 2, intE);
                document.getElementById('Panel1').scrollTop = strPos;
            }
        }
        function SetDivPosition() {
            var intY = document.getElementById('Panel1').scrollTop;
            document.title = intY;
            document.cookie = "yPos=!~" + intY + "~!";
        }
    
    
       //Note: "Panel1" Panel id or div id for which u want to maintain scroll position
    

    【讨论】:

    • 我不得不稍作修改并使用以下命令使其工作:yPos = $('#<%=MyListBox.ClientID %>').scrollTop(); 提取beginRequestHandler 中的数据,$('#<%=MyListBox.ClientID %>').scrollTop(yPos); 将其放回endRequestHandler
    【解决方案3】:

    似乎下面的代码示例以如下方式滚动:

    • Internet Explorer 8:回发后,所选项目是第一个可见项目。

    • Firefox:回发后,所选项目始终可见(但可能是最后一个可见项目)。

    • Chrome:如您所说,回发后,由于列表框滚动到顶部,所选项目可能会被隐藏。

    ABCDEFGH列表框> 内容模板>

    【讨论】:

    • Firefox 会意外地滚动到所选项目的顶部。 At first, I thought it might be because of the number of items in the listbox, but when select a particular item... sometimes it stays visible after a postback, and sometimes firefox scrolls to the top instead.该列表没有被重建,并且在单击任何项​​目时都会发生同样的事情,因此它显然是一个 firefox 错误,并且它在 3.0.13 版本中仍然存在。
    【解决方案4】:

    您仍然可以使用包含ListBoxUpdatePanel 实现部分回发,但通过在UpdatePanel 上设置以下内容来防止它被新实例覆盖:

    ChildrenAsTriggers="False"
    

    这如MSDN中所述:

    获取或设置一个值,该值指示是否立即回发 UpdatePanel 控件的子控件更新面板的内容。 如果您不想,请将 ChildrenAsTriggers 属性设置为 false 从 UpdatePanel 控件的直接子控件回发到 导致面板内容的更新。

    对此的一个警告是,如果您尝试从服务器端对 ListBox 进行任何其他可视化操作(即在回发的项目中添加 CSS 属性),那么您将不会看到它们呈现直到另一个发生不相关的回发。如果您所做的只是进行选择,那么设置 ChildrenAsTriggers="False" 将起作用。

    【讨论】:

      【解决方案5】:

      对于我正在处理的企业应用程序,事实证明 MasterPage.Master 页面正在处理 Sys.WebForms.PageRequestManager.getInstance().add_endRequest 事件并在其中设置 window.scroll(0,0)。内容页面显然在内容页面的 UpdatePanel 的每个触发器上执行 window.scroll(0,0)。我尝试覆盖内容页面中的 add_endRequest 功能,但无法使其正常工作。最终我只是修改了 Master.Master 不做 window.scroll(0,0)。

      【讨论】:

        猜你喜欢
        • 2017-08-31
        • 2014-07-13
        • 2013-05-25
        • 1970-01-01
        • 2013-07-12
        • 2017-08-02
        • 1970-01-01
        • 1970-01-01
        • 2011-09-28
        相关资源
        最近更新 更多