/    Sign up×
Community /Pin to ProfileBookmark

adding onclick with createElement

This is driving me insane. I’m trying to use createElement inside a loop to make some <divs>, each of which has an onclick event. I threw together this test page to demonstrate it:

[CODE]
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
<html xmlns=”http://www.w3.org/1999/xhtml”>
<head>
<meta http-equiv=”Content-Type” content=”text/html; charset=utf-8″ />
<title>Untitled Document</title>

<style type=”text/css”>

.btn
{
width:100px;
height:50px;
background-color:#eeeeee;
border:1px solid black;
margin-bottom:10px;
}
</style>

<script language=”javascript”>
function test()
{
for(var x=0;x<5;x++)
{
yay=document.createElement(‘div’)
yay.className=”btn”

yay.id=’yay’+x

yay.innerHTML=’lorem’

yay.onclick=function(){alert(x)}
document.body.appendChild(yay)
}
}
</script>

</head>

<body onload=”test()”>

</body>
</html>

[/CODE]

When I click on any of the boxes it alerts “5”, the final value of x after the loop ends, instead of what the value of x was when the loop executed and created the element (“0”, “1”, “2”, etc.). This is happening if FF and ie.

I also noticed in Firebug if I put a breakpoint on the “yay.onclick=function(){alert(x)}” line that it will break everytime I click on one of the boxes. Very strange…

How can I put in a variable on the yay.onclick=function(){alert(x)} line and have it “stick”? Thanks!

to post a comment
JavaScript

8 Comments(s)

Copy linkTweet thisAlerts:
@FangMar 26.2010 — Simplest:yay.count=x;
yay.onclick=function(){alert(this.count)}

or retrieve it from the id value
Copy linkTweet thisAlerts:
@raphael75authorMar 29.2010 — Thanks, it worked. Although it seems really wierd that it works like that.
Copy linkTweet thisAlerts:
@KorMar 29.2010 — Thanks, it worked. Although it seems really wierd that it works like that.[/QUOTE]
What's so weird? Without "sticking" it as property of the object, the [B]x[/B] variable will always have the last value after the loop is over. A primitive can not have multiple values.
Copy linkTweet thisAlerts:
@raphael75authorMar 29.2010 — But each one of those divs is a different object. At the time they're being created x has a different value each time through the loop so I don't see why it wouldn't keep that value. How is it different from doing it this way:

<div onclick="alert('1')" class="btn>...</div>

<div onclick="alert('2')" class="btn>...</div>

<div onclick="alert('3')" class="btn>...</div>

etc.

It's not a huge issue because I was able to create the "custom" attribute which holds the value of x.
Copy linkTweet thisAlerts:
@FangMar 29.2010 — Your original script does this:&lt;div onclick="alert(x)" class="btn&gt;...&lt;/div&gt;
&lt;div onclick="alert(x)" class="btn&gt;...&lt;/div&gt;
&lt;div onclick="alert(x)" class="btn&gt;...&lt;/div&gt;
The JavaScript function is bound at runtime (onclick), not at creation (the loop). The value of 'x' is it's value at loop termination.
Copy linkTweet thisAlerts:
@McVitasAug 30.2014 — Your original script does this:&lt;div onclick="alert(x)" class="btn&gt;...&lt;/div&gt;
&lt;div onclick="alert(x)" class="btn&gt;...&lt;/div&gt;
&lt;div onclick="alert(x)" class="btn&gt;...&lt;/div&gt;
The JavaScript function is bound at runtime (onclick), not at creation (the loop). The value of 'x' is it's value at loop termination.[/QUOTE]


Allright so you more or less explained this behavior which no doubt confuses many people, BUT you did not propose any simple solution. How can we set an onclick property to a newly created DOM element so it remembers the actual VALUE in time of setting and not the variable name? That would be great. Thanks
Copy linkTweet thisAlerts:
@rootAug 31.2014 — You could...

[CODE]yay.onclick=function(){alert(x)}[/CODE]

change to

[CODE]yay.onclick=function(){alert(parseInt( this.id ))}[/CODE]
Copy linkTweet thisAlerts:
@vwphillipsAug 31.2014 — [CODE]<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>

<style type="text/css">

.btn
{
width:100px;
height:50px;
background-color:#eeeeee;
border:1px solid black;
margin-bottom:10px;
}
</style>

<script language="javascript">
function test()
{
for(var x=0;x<5;x++)
{
yay=document.createElement('div')
yay.className="btn"

yay.id='yay'+x

yay.innerHTML='lorem'

document.body.appendChild(yay)
addevt(yay,'click',clickme,x);
}
}

function clickme(x)
{
alert(x);
}

function addevt(o,t,f,p){
o.addEventListener?o.addEventListener(t,function(e){ return f(p);},false):o.attachEvent?o.attachEvent('on'+t,function(e){ return f(p); }):null;
}

</script>

</head>

<body onload="test()">



</body>
</html>[/CODE]


or

[CODE]<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>

<style type="text/css">

.btn
{
width:100px;
height:50px;
background-color:#eeeeee;
border:1px solid black;
margin-bottom:10px;
}
</style>

<script language="javascript">
function test()
{
for(var x=0;x<5;x++)
{
yay=document.createElement('div')
yay.className="btn"

yay.id='yay'+x

yay.innerHTML='lorem'

document.body.appendChild(yay)
clickme(yay,x);
}
}

function clickme(o,x)
{
o.onclick=function(){ alert(x); }
}


</script>

</head>

<body onload="test()">



</body>
</html>[/CODE]
×

Success!

Help @raphael75 spread the word by sharing this article on Twitter...

Tweet This
Sign in
Forgot password?
Sign in with TwitchSign in with GithubCreate Account
about: ({
version: 0.1.9 BETA 5.18,
whats_new: community page,
up_next: more Davinci•003 tasks,
coming_soon: events calendar,
social: @webDeveloperHQ
});

legal: ({
terms: of use,
privacy: policy
});
changelog: (
version: 0.1.9,
notes: added community page

version: 0.1.8,
notes: added Davinci•003

version: 0.1.7,
notes: upvote answers to bounties

version: 0.1.6,
notes: article editor refresh
)...
recent_tips: (
tipper: @AriseFacilitySolutions09,
tipped: article
amount: 1000 SATS,

tipper: @Yussuf4331,
tipped: article
amount: 1000 SATS,

tipper: @darkwebsites540,
tipped: article
amount: 10 SATS,
)...