onclick

I am writing a script that need to change the onclick attribute of DIVs.  I can't simply use:

var myvar='aa';
my_div.onclick="myfunction(myvar)";

not sure why, but it doesn't work.  I am going to be using a loop and changing a bunch of onclick attributes at once, so the "myvar" variable, will be the incriment variable.  I tried:

my_div.onclick=function(){myfunction(myvar);};

but again, it did not work.  myvar was not passed in correctly because it uses the max value of the loop, because when that 'function' gets called, it goes and finds myvar, instead of replacing myvar when I create the function.  

So the question.  I need to know how to change the onclick attribute of a DIV via javascript and have the function the onclick is changed to accept a parameter that can not be hard coded.

Any help would be great.

Thanks,
Matt
LVL 6
mattjp88Asked:
Who is Participating?
 
archrajanCommented:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE> New Document </TITLE>

</HEAD>

<BODY>
<div>div 1</div>
<div>div 2</div>
<div>div 3</div>
<div>div 4</div>


<input type = "button" value = "click here to add onclick event of div" onclick = "doit()">
<script>
function alertdiv(obj)
{
alert(obj.innerHTML)
}
function doit()
{
var divs = document.getElementsByTagName("div")
for(i=0; i <divs.length; i++)
{
divs[i].onclick = new Function("alertdiv(this)");

}
}


</script>
</BODY>
</HTML>
0
 
smidgie82Commented:
Hi mattjp88,

Unfortunately, you cannot pass arguments to event handlers.  This may sound wrong, but when you register an inline event handler (e.g., <a name="link1" href="#" onclick="some_func('one', 'two');">), you're actually declaring an anonymous function that accepts no parameters, and either passes hard-coded values (e.g., strings), or global variables to other functions.  That means that the onclck="some_func('one', 'two');" is equivalent to document.links["link1"].onclick=function(){some_func('one', 'two');};

If you want to dynamically register an event listener, you don't include the parentheses, because that registers the RETURN VALUE of the function as the event handler.  Rather, use the syntax:

my_div.onclick=myfunction;

You'll have to come up with some other means for keeping track of the value of myvar between calls.  For instance, make it a global variable, and have each call to myfunction increment it by one from within myfunction().

Alternatively, you can use the Function object (as archrajan posted) to create a function.  Still, though, you're actually creating an anonymous function.  That's why your previous attempts failed.  

Archrajan's code, modified for your use (so if this part helps, give him the points):
my_div.onclick=new Function("myfunction(myvar)");
0
 
mattjp88Author Commented:
I know I can always resort to encasing my text in an A tag and then making the href javascript:void(myfunction('some variable')).  With that, I can put the variable value right in where it belongs, instead of passing that vairable itself.  I'll have to think about some way to maybe track which div has been clicked.  Each DIV does have a unique id tag, so maybe some ifs to figure it out.  I'll play around and report back with what works.  

Thanks for your help,
Matt
0
Ultimate Tool Kit for Technology Solution Provider

Broken down into practical pointers and step-by-step instructions, the IT Service Excellence Tool Kit delivers expert advice for technology solution providers. Get your free copy now.

 
dakydCommented:
Matt,

One possible work around is to take the parameter you want to pass, and then assign it to the actual object whose onclick you're assigning.  Then, you can get it back out from the object whose onclick you called.  So, say you want <object> to have an onclick of "myFunction(myVar)".  Give <object> a property (I'll call it myProp), and then set <object>.myProp = myVar.  Now, your function call can use myFunction(this.myProp), and you have essentially passed that parameter to the event handler.

Here's a sample illustrating what I'm talking about:

<html>
<head>
<script type="text/javascript">
function setOnclicks()
{
  var divs = document.getElementsByTagName("div")
  for(i=0; i <divs.length; i++)
  {
    divs[i].onclick = function() {alertdiv(this.myIndex)};
    divs[i].myIndex = i;
  }
}

function alertdiv(param)
{
  alert(param);
}
</script>
</head>

<body>
<div>div 1</div>
<div>div 2</div>
<div>div 3</div>
<div>div 4</div>

<input type="button" value="click here to add onclick event of div" onclick="setOnclicks()">
</body>
</html>

If that doesn't make sense, or you have any questions, ask away.  Hope that helps.


<as an aside>

@smidgie82
You're technically right that event handlers don't usually accept arguments (other than event), but under some circumstances, you can fake it well enough that it doesn't really matter.  For example:

<html>
<head>
<script type="text/javascript">
function setOnclicks()
{
  var divs = document.getElementsByTagName("div")
  var localVariable = document.getElementById("div1").innerHTML;
  divs[0].onclick = function() {alert(localVariable)};
}
</script>
</head>

<body>
<div id="div1">hello world</div>
<input type="button" value="add onclick event to div" onclick="setOnclicks()">
</body>
</html>


In this case, I don't *pass* localVariable to the event handler, but the event handler nevertheless has access to that variable when it executes.  For all intents & purposes, I can treat localVariable as a parameter to my event handler (notice, it's also a local variable within setOnclicks(), rather than a global variable).

That probably brings up the question of why that doesn't work in this case ... it has to do with the scope & execution context for each function.  The simplest answer I can provide is that, the variable is defined within the event handler, but its value is not looked up until execution time.  In my simple example, localVariable never changes, so you can abstract all of that away.  In the case of the for loop, i *does* change, so looking up its value after the loop has finished gives the behavior that Matt pointed out - it always spits out the last value it contained.

I just finished re-learning how all of this works recently, and I found this link incredibly useful in explaining it:
http://jibbering.com/faq/faq_notes/closures.html

It's not the most thrilling read, but it does explain everything to great detail.
0
 
ZvonkoSystems architectCommented:
Nice to see you again here Archana :-)

Archana already showed what you have to do:

my_div.onclick=new Function("myfunction('"+myvar+"');");


0
 
dakydCommented:
I disagree, Zvonko, because of this:
>> the "myvar" variable, will be the incriment variable.

Modifying Archana's sample script to account for this requirement, you'd have this:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE> New Document </TITLE>

</HEAD>

<BODY>
<div>div 1</div>
<div>div 2</div>
<div>div 3</div>
<div>div 4</div>


<input type = "button" value = "click here to add onclick event of div" onclick = "doit()">
<script>
function alertdiv(param)
{
alert(param)
}
function doit()
{
var divs = document.getElementsByTagName("div")
for(i=0; i <divs.length; i++)
{
divs[i].onclick = new Function("alertdiv(i)");
}
}
</script>
</BODY>
</HTML>

If you do that, every single div will alert the last value of i (the "increment variable"), rather than having each one alert the value that i had at the time it was used in the for loop.  Hence my idea to assign i's value to the object, and then get it back out.
0
 
ZvonkoSystems architectCommented:
In upper example is this my previously proposed statement:

divs[i].onclick = new Function("alertdiv('"+i+"');");

0
 
dakydCommented:
*sigh* Sometimes I'm just stupid ... you're right, that'll work just fine.
0
 
ZvonkoSystems architectCommented:
Not a problem at all :-)
0
 
mattjp88Author Commented:
Sorry about the delay.  Finals killed me.  But they are over now.  I ended up using a different method for working around what I thought was initially impossible.

Splitting points.  I used archrajan's method of passing 'this' to get the DIV's unique id number from its ID tag.  But also split to Zvonko because his does work, just a little too late for me to use it.

Thanks all,
Matt
0
 
ZvonkoSystems architectCommented:
Thanks.
See you.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.