/    Sign up×
Community /Pin to ProfileBookmark

Changing onclick Dynamically, previous change doesn’t stick

I have a set of images that I can click and when I click an image I want to change that images onclick event. The thing is each image has an number and when the user clicks on the image the image’s onclick has to fire to a function with its corresponding number.

I am able to change the onclick of an image when I click on it HOWEVER when I click on a second image my first images onclick event gets wiped.

[CODE]
//i has the value of the clicked image
//image_id is the number of the image
//This section of code is called when an image is clicked.
document.getElementById(‘article_image_’+i).onclick=function(){grab_image(image_id,’event’);document.getElementById(‘article_bodies’).removeChild(document.getElementById(‘article_image_’+i));}
[/CODE]

I’m usually really good at debugging things like this but for some reason I can’t figure this ordeal out.

Help would be awesome!!

to post a comment
JavaScript

16 Comments(s)

Copy linkTweet thisAlerts:
@FangMar 04.2009 — Why passing a variable doesn't work like that: http://www.webdeveloper.com/forum/showpost.php?p=983738&postcount=11
Copy linkTweet thisAlerts:
@Farel321authorMar 04.2009 — Hey Fang, first off thank you for your reply I appreciate it greatly.

However, I've tried both methods that you spoke of:

[CODE] document.getElementById('article_image_'+i).onclick=function(image_id,i)
{
return function(e)
{
grab_image(image_id,'event');
document.getElementById('article_bodies').removeChild(document.getElementById('article_image_'+i));
};
}
[/CODE]


and

[CODE]
document.getElementById('article_image_'+i).onclick=new Function("grab_image("+image_id+",'event');document.getElementById('article_bodies').removeChild(document.getElementById('article_image_"+i+"'));");
[/CODE]


I placed a while loop to circulate through all of the article_images and once I click a second image the previous images onclick becomes "undefined."

Also, The second function works as intended and the first function never actually does the code I ask it to.

Any ideas?
Copy linkTweet thisAlerts:
@FangMar 04.2009 — I click on it HOWEVER when I click on a second image my first images onclick event gets wiped.[/QUOTE]If you are doing this in a loop, only change the onclick for the object in question.

Surely just passing the object to a function to alter the onclick would be enough rather than looping through all objects?
Copy linkTweet thisAlerts:
@Farel321authorMar 04.2009 — To be precise first I look for the next available 'article_image'.

Here's the code that occurs when I click on an image

[CODE]
i = 0;
while(document.getElementById('article_image_'+i) != null)//Find the next available id
i++;

//This just creates the article_image and adjusts the ID accordingly
//currently_showing contains the id of what we want to adjust
document.getElementsByName('pic_holder_'+currently_showing)[0].id="article_image_"+i;

//Adjust the name and class name of our new article_image
document.getElementById('article_image_'+i).name="article_image_"+i;
document.getElementById('article_image_'+i).className += ' held';
var image_id = current_image_id;//The current_image that we've clicked on, current_image_id is a global

alert("The current image id is " + image_id + " and i is " + i);

//This is the first scenario that we spoke of, commented out for now
/*
document.getElementById('article_image_'+i).onclick=function(image_id,i)
{
return function(e)
{
grab_image(image_id,'event');
document.getElementById('article_bodies').removeChild(document.getElementById('article_image_'+i));
};
}
*/

//And here's the second onclick adjustment
document.getElementById('article_image_'+i).onclick=new Function("grab_image("+image_id+",'event');document.getElementById('article_bodies').removeChild(document.getElementById('article_image_"+i+"'));");


//Store the clicked image in the held_images array(global)
held_images[i] = document.getElementById('article_image_'+i);

//Look through each article image and then alert its onclick event(previous onclicks for some reason get sset to undefined)
i=0;
while(document.getElementById('article_image_'+i) != null){
alert("i = " + i + "nnn" + document.getElementById('article_image_'+i).onclick);i++;}
[/CODE]

I'm only setting the next available article_image which really confuses me as to why my previous image clicks 'onclick' gets reset to undefined.

Hopefully this helps, if you have any questions please ask.
Copy linkTweet thisAlerts:
@KorMar 04.2009 — The increment [B][COLOR="SeaGreen"]i[/COLOR][/B] is part of the loop, not a steady argument. You must first [I]"stick"[/I] it as a property of that element:
<i>
</i>var mydiv=document.getElementById('article_image_'+i);
[COLOR="Blue"]mydiv.ind=i;[/COLOR]//stick the increment as an object's custom property
mydiv.onclick=function(image_id,[COLOR="Blue"]this.ind[/COLOR])
Copy linkTweet thisAlerts:
@FangMar 04.2009 — This changes the id of an image. The same image has it's name changed. ??? document.getElementsByName('pic_holder_'+currently_showing)[0].id="article_image_"+i;

//Adjust the name and class name of our new article_image
document.getElementById('article_image_'+i).name="article_image_"+i;
Are you sure you are not creating duplicate ids and/or names which will certainly cause referencing problems?
Copy linkTweet thisAlerts:
@KorMar 04.2009 — and:
<i>
</i>...
document.getElementById('article_bodies').removeChild(document.getElementById('article_image_'+[COLOR="Blue"]this.ind[/COLOR]));

Or something like that
Copy linkTweet thisAlerts:
@Farel321authorMar 04.2009 — Wow, thank you for the replies. First off thank you Kor for that Idea. To be honest I never thought of creating my own attribute to make things "stick". This is something that can be of huge use!

As for the indexing problem the quick and simple answer to that question is that through lots of debugging i've made sure that there's no indexing problems going on. If you look through the code that I posted I have some alert statements setup just to make sure i'm not indexing any wrong elements.

As for this problem I believe I have it figured out now thanks to both of your help. I did some further debugging and it seems as though every time the innerHTML of my parent element is changed it resets all dynamically created elements through my javascript. I've had this problem before in some of my old programs but i've never found a way around it.
Copy linkTweet thisAlerts:
@FangMar 04.2009 — honest I never thought of creating my own attribute to make things "stick".[/QUOTE]It's invalid, use a closure as shown in the link.
Copy linkTweet thisAlerts:
@KorMar 05.2009 — It's invalid[/QUOTE]
How's that? It works. Suppose you have a collection of elements

<i>
</i>var allA=document.getElementsByTagName('a');
for(var i=0; i&lt;allA.length;i++){
allA[i].ind=i;
allA[i].onclick=function(){alert(this.ind)}
}
Copy linkTweet thisAlerts:
@Farel321authorMar 09.2009 — I've tried your method of setting an attribute however once the innerHTMl of the elements have been modified the previous attribute gets wiped
Copy linkTweet thisAlerts:
@FangMar 10.2009 — [I]ind[/I] is not a valid attribute. If you believe adding invalid content with JavaScript is a valid solution, then why would you bother to use the W3C validator at all?
Copy linkTweet thisAlerts:
@KorMar 10.2009 — [B]Fang[/B], an element is, at the same time, an [I]object[/I]. Any object, in javascript, may gain custom methods and properties. What has W3C Validator with a javascript syntax?
Copy linkTweet thisAlerts:
@FangMar 10.2009 — Producing a valid document
Copy linkTweet thisAlerts:
@KorMar 10.2009 — I don't think that W3C has a javascript validator. A valid document is an HTML, XHTML, CSS, Semantic data, RSS, RDF aso... valid.

Anyway, to come back to the point. Everything can be set, in javascript, as an [I]object[/I]. Javascript objects may have native properties and may gain custom properties. A DIV element (or any other DOM element) is an object as well. Nothing can prevent me from giving it a new javascript property. It is not an [I]custom HTML attribute[/I], it is a [I]javascript new property[/I] in a [B]JSON[/B] way. This will have no influence upon his HTML DOM behavior. The only concern I must have is to avoid using reserved words. It does not matter if my object is a HTML DOM element, a variable, a function... It is just a javascript [I]object[/I]. I may attach him a new property/method using a constructor, using the prototype method or, as I did in my example, simply by using direct (or square brackets) way, based on JSON:
<i>
</i>object.newproperty=value

or
<i>
</i>object['newproperty']=value


The above is javascript perfect valid. It has nothing to do with W3C validation (or any validation). It is just a part of the javascript syntax.
Copy linkTweet thisAlerts:
@Jeff_MottMar 10.2009 — I'm actually with Kor on this one. :eek:

The DOM defines an interface—a set of methods and properties—for various kinds of objects. But there's no reason objects of those types can't be extended to include additional methods and additional properties.

My personal preference is to use closures; I like the encapsulation. But adding properties to an object is by no means invalid.
×

Success!

Help @Farel321 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 6.2,
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: @meenaratha,
tipped: article
amount: 1000 SATS,

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

tipper: @AriseFacilitySolutions09,
tipped: article
amount: 1000 SATS,
)...