Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 36670
  • Last Modified:

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
0
mattjp88
Asked:
mattjp88
  • 4
  • 3
  • 2
  • +2
2 Solutions
 
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
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
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

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

  • 4
  • 3
  • 2
  • +2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now