Firefox中的Asp.Net表单DefaultButton错误

时间:2020-03-05 18:49:26  来源:igfitidea点击:

.Net为带有" DefaultButton"属性集的表单生成的代码包含不良的javascript,该JavaScript允许该功能在IE中运行,但不能在其他浏览器(特定于Firefox)中运行。

按下Enter键会在所有浏览器中提交该表单,但是Firefox在<textarea>控件内部发生时不能忽略该按键。结果是一个多行文本区域控件,在Firefox中不能为多行,因为Enter键提交表单而不是创建新行。

有关该错误的更多信息,请在此处阅读。

可以在Asp.Net 3.0+中修复此问题,但仍必须为2.0创建解决方法。

对于最简单的解决方法(黑客看起来不像黑客= D)有什么想法吗?上面链接中的解决方案使我有些害怕,因为它很容易产生意想不到的副作用。

解决方案

回答

对于此特定问题,原因是因为
ASP.NET 2.0具有仅IE的一种表示法:event.srcElement不可用
FireFox(改为使用event.target):

function WebForm_FireDefaultButton(event, target) {
if (!__defaultFired && event.keyCode == 13 && !(event.srcElement && 
(event.srcElement.tagName.toLowerCase() == "textarea"))) {
var defaultButton;
if (__nonMSDOMBrowser) {
defaultButton = document.getElementById(target);
}
else {
defaultButton = document.all[target];
}
if (defaultButton && typeof(defaultButton.click) != 
"undefined") {
__defaultFired = true;
defaultButton.click();
event.cancelBubble = true;
if (event.stopPropagation) event.stopPropagation();
return false;
}
}
return true;
}

如果我们将前两行更改为:

function WebForm_FireDefaultButton(event, target) {
var element = event.target || event.srcElement;
if (!__defaultFired && event.keyCode == 13 && !(element && 
(element.tagName.toLowerCase() == "textarea"))) {

将更改的代码放入文件中,然后执行

protected void Page_Load(object sender, EventArgs e)
{
ClientScript.RegisterClientScriptInclude("js1", "JScript.js");
}

然后它将适用于IE和FireFox。

来源:

http://www.velocityreviews.com/forums/t367383-formdefaultbutton-behaves-incorrectly.html

回答

我使用从codesta改编的此功能。 [编辑:我看到的是同一个人,这吓到你了!哎呀。那就帮不了你。

http://blog.codesta.com/codesta_weblog/2007/12/net-gotchas---p.html。

我们可以像这样用div包围代码来使用它。我们可以将Form子类化,以自动包含它。我没有用太多,所以没有。

<div onkeypress="return FireDefaultButton(event, '<%= aspButtonID.ClientID %>')">
    (your form goes here)
</div>

这是功能。

function FireDefaultButton(event, target) 
{
    // srcElement is for IE
    var element = event.target || event.srcElement;

    if (13 == event.keyCode && !(element && "textarea" == element.tagName.toLowerCase())) 
    {
        var defaultButton;
        defaultButton = document.getElementById(target);

        if (defaultButton && "undefined" != typeof defaultButton.click) 
        {
            defaultButton.click();
            event.cancelBubble = true;
            if (event.stopPropagation) 
                event.stopPropagation();
            return false;
        }
    }
    return true;
}

回答

似乎不再需要harpo链接到的fix codesta.com,因为fix event.srcElement未集成在ASP.NET 3.5中。但是,DefaultButton的实现确实仍然存在一些问题,因为在太多情况下,它会捕获Enter键。例如:如果我们使用选项卡激活了表单中的按钮,则按Enter键应单击该按钮,而不提交表单。

在ASP.NET网页的底部包括以下JavaScript代码,以使Enter发挥应有的作用。

// Fixes ASP.NET's behavior of default button by testing for more controls
// than just textarea where the event should not be caugt by the DefaultButton
// action. This method has to override ASP.NET's WebForm_FireDefaultButton, so
// it has to included at the bottom of the page.
function WebForm_FireDefaultButton(event, target) {
  if (event.keyCode == 13) {
    var src = event.srcElement || event.target;
    if (!(
      src
      &&
      (
        src.tagName.toLowerCase() == "textarea"
        || src.tagName.toLowerCase() == "a"
        ||
        (
          src.tagName.toLowerCase() == "input"
          &&
          (
            src.getAttribute("type").toLowerCase() == "submit"
            || src.getAttribute("type").toLowerCase() == "button"
            || src.getAttribute("type").toLowerCase() == "reset"
          )
        )
        || src.tagName.toLowerCase() == "option"
        || src.tagName.toLowerCase() == "select"
      ) 
    )) {
      var defaultButton;
      if (__nonMSDOMBrowser) {
        defaultButton = document.getElementById(target);
      }
      else {
        defaultButton = document.all[target];
      }
      if (defaultButton && typeof (defaultButton.click) != "undefined") {
        defaultButton.click();
        event.cancelBubble = true;
        if (event.stopPropagation) event.stopPropagation();
        return false;
      }
    }
  }
  return true;
}