简体   繁体   中英

How do I add parameters to an event handler in javascript?

and thanks for looking.

Currently I am implementing code from this example. In my aspx file, I have Label1 and Textbox1 defined. In my aspx.cs file, I am setting the Label1.Text property to a random string in the Page_Load method.

In the .js file I have included, I have:

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);
}

Now, I want to add more labels (and corresponding textboxes), but I do not want the overhead of defining separate handlers for each of the additional events, ie I want to avoid this:

$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);
...

How can I pass a parameter to the handler that will identify the sender accurately, and have the handler use 'this' or something. Also of note, I want to be able to identify the index of the Label (1,2,3...) because I have to edit the corresponding textbox as well. FOr instance, the current implementation of Label1_Click looks like this:

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

Thanks, you guys.

Well, $addHandlers can help speed up the process of adding handlers... also, in JS you can attach miscellaneous data to objects by doing: Label1["somenewproperty"] = value; and so you can attach certain attributes and check in the event handlers... that does take up resources though, so be careful how much you do this...

On some level, how is JS supposed to know the objects you want to listen to and what order the objects are in, to reduce the amount of code? Maybe storing an array of textboxes and labels, and referring to those objects by index, but on some level, you can't get away from certain plumbing code.

HTH.

You can try creating a delegate. For example with your labels:

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

function LabelClick(sender)
{
 /..
}

I know this is an old question but yesterday I faced this very same problem and here is the solution I came of with.

I don't like it a lot but haven't found an easier way: I use a custom CssClass for every label I want to be linked with a textbox by this method (and the same for the textbox). Then I iterate them and attach the corresponding handler depending on if it is a label or a button.

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);
  }
}

The next step is to access the generic control inside the method handler. This is quite easy with the this reference. Example:

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

But there is a problem here: How do I know that a certain label pairs with a certain textbox? I use a very similar id for both controls. ASP will add it's viewstate weird nomenclature after rendering the page so I need to use very dirty tricks to get rid of the extra text. Then I iterate the textbox controls and if one matches the label on the handled event then I can work with them like in the example you posted:

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();
        }            
    }
}

In this case my label and textbox are declared this way. Note the very similar nomenclature:

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

Hope it helps :)

there are many ways, but this one works perfectly in any browser and you don't need a library.

I append an onclick handler to every input on this page and give it 2 parameters, that I get from a 2-dimensional array. I used a closure to make sure the handler still has access to the given parameters. I also made me a global object (p from page), so I don't clutter the global namespace with variables.

<!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> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM