65.9K
CodeProject 正在变化。 阅读更多。
Home

ASP.NET 客户端焦点助手

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.89/5 (9投票s)

2004年1月13日

3分钟阅读

viewsIcon

139427

downloadIcon

1219

帮助类,用于生成和注册客户端脚本,该脚本在页面加载期间将焦点设置到控件。

Sample Image - ClientSideFocus.jpg

引言

我今天一直在尝试设置客户端控件的焦点,我认为提交这个可能很有用。 我希望我没有错过已经内置在ASP.NET中的方法。

我创建了一个帮助类,使您可以通过单个调用设置客户端焦点。 我决定不创建Page类的子类,因为我认为帮助类方法更好,更易于在现有系统上实现。

最初的工作方式

所需要的只是控件所在的表单的ID和控件本身的ID。 有几个重载函数可以根据您传递的服务器控件类型自动查找这些ID。

private void Page_Load(object sender, System.EventArgs e)
{
  if( !this.IsPostBack )
  {
    McGiv.Web.UI.ClientSideFocus.setFocus(this.TextBox1);
    this.ViewState["focus"] = "WebControl";
  }
}

然后生成JavaScript脚本并将其注册到给定的Page对象。

脚本本身会复制document.body.onload函数,并将其替换为焦点设置函数,该函数又调用原始的onload函数,这意味着您不必修改页面中可能存在的任何现有onload脚本。

// save original function

 if(document.body.onload)
  original = document.body.onload;

 // override original function

 document.body.onload = document_onLoad;

 function document_onLoad()
 {
  try
  {
   document.FormID.ControlID.focus();
  }
  catch(e){}

  // call original function

  original();
 }


 function original()
 {
  // do nothing if original is null

 }

现在的工作方式

在得知原始代码可能会窃取另一个窗口的焦点(这可能会很烦人)之后,我从使用document.body.onload事件切换到document.body.onfocus事件。

    var called = false;

    if(document.body.onfocus)
        orig_document_body_onfocus = document.body.onfocus;

    document.body.onfocus = document_body_onfocus;


    function setFocus()
    {
        var control = document.getElementById("html");
        if(control)
            control.focus();
    }


    function orig_document_body_onfocus(){}
    
    function document_body_onfocus ()
    {
        if( !called )
        {
            called = true;
            setFocus();
        }

        orig_document_body_onfocus();
    }



    if( window.__smartNav && window.__smartNav.restoreFocus)
    {
        orig_window__smartNav_restoreFocus = window.__smartNav.restoreFocus;
        window.__smartNav.restoreFocus = window__smartNav_restoreFocus;
    }


    function orig_window__smartNav_restoreFocus(){}

    function window__smartNav_restoreFocus()
    {
        setFocus();
        orig_window__smartNav_restoreFocus
    }

我还尝试通过覆盖SmartNav.js文件中的restoreFocus函数来解决智能导航的问题,但是目前这似乎仅在我的本地计算机上有效。 这可能是由于安全问题或从远程主机加载所需的时间。

我删除了对HTML表单ID的需求,因为在ASP.NET中的大多数情况下,页面将仅使用一个表单。 仅此修改就从原始代码中删除了大约一半的内容。 如果您仍然需要引用表单的ID以及控件ID,我已包含原始代码。

已知问题

当前,启用智能导航后,帮助类无法正常运行。

演示

我包含了一个简单的演示,该演示在WebControlHtmlControl和一个硬编码的HTML输入控件之间切换焦点。

我使用viewstate来跟踪哪个控件具有焦点。

private void Button1_Click(object sender, System.EventArgs e)
{
  string focus = this.ViewState["focus"] as string;
  if( focus == null )
    focus = "WebControl";
  switch(focus)
  {
    case "Html":
    {
      McGiv.Web.UI.ClientSideFocus.setFocus(this.TextBox1);
      this.ViewState["focus"] = "WebControl";
      break;
    }
    case "HtmlControl":
    {
      McGiv.Web.UI.ClientSideFocus.setFocus(this, "html");
      this.ViewState["focus"] = "Html";
      break;
    }
    case "WebControl":
    {
      McGiv.Web.UI.ClientSideFocus.setFocus(this.HtmlControl1);
      this.ViewState["focus"] = "HtmlControl";
      break;
    }
  }
}

为了使其工作,请将演示文件解压缩到映射到https:///ClientSideFocus/的虚拟目录中。

我还设置了一个在线演示这里

享受。

版本历史

  • 版本1.3:2003年1月21日,星期三
    • 修复了空对象JavaScript错误。
  • 版本1.2:2003年1月20日,星期二
    • 将对setFocus的调用从document.body.onload事件移至document.body.onfocus事件。 这样可以防止从具有焦点的另一个浏览器窗口中获取焦点。
    • 发现该代码仅在我的本地计算机上使用智能导航有效,而在我的远程主机上无效。 不知道这是安全问题还是加载时间问题。
  • 版本1.1:2003年1月14日,星期三
    • onload事件中删除脚本。 允许它也可以与Mozilla浏览器一起使用。
    • 使用getElementById([control name])代替使用[form name].[control name]
    • 无需搜索表单的ID - 使用ASP.NET,通常仅使用1个表单,从而无需提供表单ID。
    • 覆盖restoreFocus智能导航功能。 现在在启用智能导航时有效。
  • 版本1.0:2003年1月13日,星期二
    • 如果WebForm上启用了智能导航,则可以正常工作。 仅在IE 6.1上进行了测试。
© . All rights reserved.