【问题标题】:Selecting the contents of an ASP.NET TextBox in an UpdatePanel after a partial page postback在部分页面回发后在 UpdatePanel 中选择 ASP.NET 文本框的内容
【发布时间】:2011-02-21 14:48:45
【问题描述】:

在 IE 8 的 UpdatePanel 中选择 TextBox 中的文本时遇到问题。考虑一个包含单个 UpdatePanel 的非常简单的页面。在该 UpdatePanel 中有两个 Web 控件:

  1. 具有三个静态定义的列表项的 DropDownList,其 AutoPostBack 属性设置为 True,并且
  2. TextBox Web 控件

DropDownList 为其 SelectedIndexChanged 事件提供了一个服务器端事件处理程序,并且在该事件处理程序中有两行代码:

TextBox1.Text = "Whatever";
ScriptManager.RegisterStartupScript(this, 
                      this.GetType(), 
                      "Select-" + TextBox1.ClientID,
                      string.Format("document.getElementById('{0}').select();", 
                                                       TextBox1.ClientID), 
                      true);

这个想法是,每当用户从 DropDownList 中选择和项目时,都会有部分页面回发,此时 TextBox 的 Text 属性被设置和选择(通过注入的 JavaScript)。不幸的是,这不能按原样工作。 (我也尝试将脚本放在 pageLoad 函数中,但没有成功,如:ScriptManager.RegisterStartupScript(..., "function pageLoad() { ... my script .. . }");) 发生的情况是代码运行,但页面上的其他内容在部分页面回发结束时获得焦点,导致 TextBox 的文本被取消选择。

我可以通过使用 JavaScript 的 setTimeout 来“解决”这个问题,以延迟我的 JavaScript 代码的执行。例如,如果我将发出的 JavaScript 更新为以下内容:

setTimeout("document.getElementById('{0}').select();", 111);

它“有效”。我将作品放在引号中,因为它适用于我计算机上的这个简单页面。在较慢的计算机上的更复杂的页面中,在部分页面回发上客户端和服务器之间传递了更多标记,我必须将超时时间提高到一秒以上才能使其正常工作。我希望有一种更万无一失的方法来实现这一目标。与其说“延迟 X 毫秒”,不如说“当你不打算窃取焦点时运行这个”。

令人困惑的是 .Focus() 方法运行良好。也就是说,如果我废弃我的 JavaScript 并将其替换为对 TextBox1.Focus(); 的调用,那么 TextBox 将获得焦点(尽管未选择文本)。我检查了 MicrosoftAjaxWebForms.js 的内容,发现焦点是在注册脚本运行后设置的,但我的 JavaScript 技能不足以解码这里发生的一切以及为什么在选定文本到部分页面回发结束之间,选定的文本处于未选定状态。我也尝试过使用 Firebug 的 JavaScript 调试器,发现当我的脚本运行时,TextBox 的文本被选中。当我继续浏览它时,文本仍然处于选中状态,但是在离开脚本的最后一行之后(显然)它突然被取消选中。

有什么想法吗?我正在拔头发。

提前谢谢...

编辑:经过进一步测试,我注意到这种行为只发生在 IE 8 中。在 Firefox、Chrome 或 Safari 中进行测试时不会发生...

【问题讨论】:

    标签: asp.net javascript updatepanel


    【解决方案1】:
    Sys.WebForms.PageRequestManager.getInstance().add_endRequest(
            function(sender, args) {
                document.getElementById('TextBox1.ClientID').focus();
            });
    

    一旦 UpdatePanel 完成它的请求,这将被调用。您还需要从 DOM 中重新拉取元素,因为在调用更新面板之前对其的任何引用都不会在更新面板完成后指向该字段。

    【讨论】:

    • 感谢您的指导。我最终做了类似的事情,这成功了。再次感谢...
    【解决方案2】:

    我没有经常使用 UpdatePanel,所以不太了解这在您的特定情况下是否有用,但使用 jQuery document.ready 包装器成功解决了焦点困难。如果您还没有使用 jQuery,它可能值得一试 - 尝试更改 RegisterStartupScript 以输出如下内容:

    $(document).ready(function() {
        document.getElementById('TextBox1.ClientID').select();
    });
    

    当然可能有非 jQuery 的方法来排序,但是这种方法通常很简单。

    【讨论】:

    • callcopse,我用 Firefox 测试了你的建议,它奏效了!!然后我尝试了我之前的尝试(在 Firefox 中),即将代码直接放入 RegisterStartupScript,放入 pageLoad,并使用 setTimeout(全部三个)。我发现它在所有三种情况下都适用于 FF。哦哦。所以我启动了 IE 8,这是我昨天用于测试的,这三种方法都没有在 IE 8 中工作。所以我们回到第一个问题,但有更多信息。 (我已更新原始问题以包含此附加信息...)
    猜你喜欢
    • 2011-04-04
    • 1970-01-01
    • 2015-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多