【问题标题】:How do I add parameters to an event handler in javascript?如何在 javascript 中向事件处理程序添加参数?
【发布时间】:2010-08-24 17:27:40
【问题描述】:

感谢您的关注。

目前我正在实现来自this 示例的代码。在我的 aspx 文件中,我定义了 Label1 和 Textbox1。在我的 aspx.cs 文件中,我在 Page_Load 方法中将 Label1.Text 属性设置为随机字符串。

在我包含的 .js 文件中,我有:

var Label1, TextBox1;

Sys.Application.add_init(AppInit);

function AppInit(sender) {
    Label1 = $get('Label1');
    TextBox1 = $get('TextBox1');

    $addHandler(Label1, "click", Label1_Click);
    $addHandler(TextBox1, "blur", TextBox1_Blur);
    $addHandler(TextBox1, "keydown", TextBox1_KeyDown);
}

现在,我想添加更多标签(和相应的文本框),但我不希望为每个附加事件定义单独的处理程序的开销,即我想避免这种情况:

$addHandler(Label1, "click", Label1_Click);
$addHandler(TextBox1, "blur", TextBox1_Blur);
$addHandler(TextBox1, "keydown", TextBox1_KeyDown);
$addHandler(Label2, "click", Label2_Click);
$addHandler(TextBox2, "blur", TextBox2_Blur);
$addHandler(TextBox2, "keydown", TextBox2_KeyDown);
...

如何将参数传递给将准确识别发件人的处理程序,并让处理程序使用“this”或其他内容。另外值得注意的是,我希望能够识别标签 (1,2,3...) 的索引,因为我还必须编辑相应的文本框。例如,Label1_Click 的当前实现如下所示:

function Label1_Click() {
    TextBox1.value = Label1.innerHTML;
    Label1.style.display = 'none';
    TextBox1.style.display = '';
    TextBox1.focus();
    TextBox1.select();
}

谢谢你们。

【问题讨论】:

  • 仅供参考 - 看起来您正在使用 Microsoft 的客户端库。根据 MS 的说法,他们正在将客户端开发工作转向 jQuery (stephenwalther.com/blog/archive/2010/03/16/…)。虽然您尝试做的事情会奏效,但我建议您试一试 jQuery,除非您正在开发服务器控件。

标签: javascript asp.net textbox label addhandler


【解决方案1】:

嗯,$addHandlers 可以帮助加快添加处理程序的过程...此外,在 JS 中,您可以通过执行以下操作将杂项数据附加到对象: Label1["somenewproperty"] = value;因此您可以附加某些属性并签入事件处理程序...虽然这确实会占用资源,所以请注意您这样做的次数...

在某种程度上,JS 应该如何知道你想听的对象以及对象的顺序,以减少代码量?也许存储一个文本框和标签数组,并通过索引引用这些对象,但在某种程度上,你无法摆脱某些管道代码。

HTH。

【讨论】:

    【解决方案2】:

    您可以尝试创建委托。例如使用您的标签:

    function AppInit(sender) {
      $addHandler(Label1, "click", Function.createDelegate(this, LabelClick());
      $addHandler(Label2, "click", Function.createDelegate(this, LabelClick());
    }
    
    function LabelClick(sender)
    {
     /..
    }
    

    【讨论】:

    • 是的,除了委托专门返回发件人。回调允许您返回任何内容(因此,如果您的回调返回发件人本身,则返回相同的内容)。事实上,如果你需要两者,你可以做 createDelegateCallback。见:blogs.lotterypost.com/speednet/2008/5/…
    【解决方案3】:

    我知道这是一个老问题,但昨天我遇到了同样的问题,这是我想出的解决方案。

    我不太喜欢它,但还没有找到更简单的方法:我为每个希望通过此方法与文本框链接的标签使用自定义 CssClass(文本框也是如此)。 然后我迭代它们并根据它是标签还是按钮附加相应的处理程序。

    var labels;
    var texts;
    
    Sys.Application.add_init(AppInit);
    
    function AppInit(sender) {
    
      labels = document.getElementsByClassName('lblDynamic');
      texts = document.getElementsByClassName('txtDynamic');
    
      for (i = 0; i < labels.length; i++)
      {
          $addHandler(labels[i], "click", Label1_Click);
      }
    
      for (i = 0; i < texts.length; i++) {
    
          $addHandler(texts[i], "blur", TextBox1_Blur);
          $addHandler(texts[i], "keydown", TextBox1_KeyDown);
      }
    }
    

    下一步是访问方法处理程序中的通用控件。使用this 参考很容易做到这一点。示例:

    function TextBox1_KeyDown(event) {
      if (event.keyCode == 13) {
        event.preventDefault();
        this.blur();
      }
    }
    

    但是这里有一个问题:我怎么知道某个标签与某个文本框配对?我对两个控件都使用了非常相似的 id。 ASP 将在呈现页面后添加它的视图状态奇怪的命名法,所以我需要使用非常肮脏的技巧来摆脱额外的文本。然后我迭代文本框控件,如果一个与已处理事件上的标签匹配,那么我可以像您发布的示例中那样使用它们:

    function Label1_Click() 
    {
        var offset = this.id.indexOf('lbl') + 3;
    
        for (j = 0; j < texts.length; j++) 
        {
            if (texts[j].id.substring(offset) == this.id.substring(offset)) 
            {
                texts[j].value = this.innerHTML;
                this.style.display = 'none';
                texts[j].style.display = '';
                texts[j].focus();
            }            
        }
    }
    

    在这种情况下,我的标签和文本框是这样声明的。请注意非常相似的命名法:

    <asp:Label runat="server" CssClass="lblDynamic" ID="lblExerciseName">My Text</asp:Label>
    <asp:TextBox runat="server" CssClass="txtDynamic" ID="txtExerciseName" Style="display: none;" />
    

    希望对你有帮助:)

    【讨论】:

      【解决方案4】:

      有很多方法,但是这个可以在任何浏览器中完美运行,并且您不需要库。

      我将 onclick 处理程序附加到此页面上的每个输入并为其提供 2 个参数,这些参数是我从二维数组中获取的。我使用了一个闭包来确保处理程序仍然可以访问给定的参数。我还让我成为了一个全局对象(p from page),所以我不会用变量来混淆全局命名空间。

      <!DOCTYPE html>
      <html>
          <head>
              <script>
                  var p = {
                      onload: function() {
                          var btns = document.getElementsByTagName("input");
                          var parameters = [["btn1 p1", "btn1 p2"], ["btn2 p1", "btn2 p2"]];
                          for(var i = 0, ceiling = btns.length; i < ceiling; i++) {
                              btns[i].onclick = function(par1, par2) {
                                  return function() {
                                      p.btnOnclick(par1, par2);
                                  };
                              }(parameters[i][0], parameters[i][1]);
                          }
                      },
                      btnOnclick: function(par1, par2) {
                          alert("par1: " + par1 + " | par2: " + par2);
                      }
                  };
              </script>
          </head>
          <body onload="p.onload()">
              <input type="button" value="button1"/>
              <input type="button" value="button2"/>
          </body>
      </html> 
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-09-23
        • 1970-01-01
        • 1970-01-01
        • 2012-04-17
        • 2017-02-28
        • 2017-09-21
        相关资源
        最近更新 更多