Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 10 of 10
  1. #1
    New to the CF scene
    Join Date
    Mar 2009
    Location
    State College, PA, USA
    Posts
    3
    Thanks
    2
    Thanked 0 Times in 0 Posts

    Simplifying a large number of similar object definitions

    I am looking for a way to simplify a large series of “object definitions” in the form:
    var Img0 ={init:function(){Img0.div = document.getElementById("img0"); Img1.init();}};
    var Img1 ={init:function(){Img1.div = document.getElementById("img1"); Img2.init();}};
    var Img2 ={init:function(){Img2.div = document.getElementById("img2"); Img3.init();}};
    .
    .
    .
    The program I have developed (for animated greeting cards) works fine but for a large number of images there are an equal number of these object definitions. I am aware of such techniques as using “+i+” in place of the numbers 0, 1, 2, ... and assigning an increasing value to i in a loop. However, I do not see a way to use such a loop here. Might there be any suggestions for doing this? I am in no hurry. Thanks.

  • #2
    Kor
    Kor is offline
    Red Devil Mod Kor's Avatar
    Join Date
    Apr 2003
    Location
    Bucharest, ROMANIA
    Posts
    8,478
    Thanks
    58
    Thanked 379 Times in 375 Posts
    If your Img0, Img1... should be global variables, the loop could be something like:
    Code:
    var i=0, d;
    while(d=document.getElementById('img'+(i++)){
    window['Img'+(i-1)]={init:function(){window['Img'+(i-1)].div = d; window['Img'+i].init();}};
    }
    KOR
    Offshore programming
    -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*

  • #3
    Senior Coder
    Join Date
    Oct 2008
    Location
    Long Beach
    Posts
    1,196
    Thanks
    36
    Thanked 164 Times in 164 Posts
    If you're looking for a fun way to incorporate semantic classifying of objects, then it would be more appropriate to control your list of img objects from a higher level (ie don't place a reference to the next img object inside each img object, instead, use a higher level array and functions to control your image collection).

    This is completely optional, there are hundreds of different ways to do things in JS, but if your project gets large it usually pays off to code semantically and object-orientedly (yes, that's a word ).

    I don't know what you intend to do with these images (if you tell me what your ultimate objective is I can help you write better code) but this should give you a start:
    Code:
    <script type="text/javascript">
    // <![CDATA[
    
    // ImageCollection JS Class
    function ImageCollection()
    	{
    	this.images = new Array();
    	this.current_index = 0;
    	this.addImages = function(ids)
    		{
    		if (typeof(id) == "string") id = [ids];
    		for (var i=0;i<ids.length;i++) this.images.push(new MyImage(ids[i]));
    		}
    	this.next = function()
    		{
    		return (this.images[++this.current_index]);
    		}
    	}
    
    // MyImage JS Class
    function MyImage(id)
    	{
    	this.ref_id = id;
    	this.div = document.getElementById("id");
    	}
    
    window.onload = function()
    	{
    	my_image_collection = new ImageCollection();
    	my_image_collection.addImages(["img0","img1","img2","img3"]);
    	alert(my_image_collection.next());
    	}
    
    // ]]>
    </script>
    Feel free to e-mail me if I forget to respond ;)
    ohsosexybrit@gmail.com

  • #4
    Regular Coder
    Join Date
    Dec 2008
    Location
    Tannhäuser Gate
    Posts
    286
    Thanks
    7
    Thanked 58 Times in 57 Posts
    I'm not sure what is the purpose of that init function. If you just want to add a reference to a DIV as a property of each of those Img objects, try this:
    Code:
    <body>
    <div id="Img0"></div>
    <div id="Img1"></div>
    <div id="Img2"></div>
    <script>
    function Img(divID){ //constructor
    	this.div=document.getElementById(divID);
    }
    for (i=0;i<3;i++){ // loop creating new instances
    eval('var Img'+i+'=new Img("Img'+i+'");');
    }
    //examples, property .div now stores a reference to another object [DIV element in that case]
    Img0.div.innerHTML="Div1";
    Img1.div.style.border="1px solid black";
    Img2.div.innerHTML=Img2.div.offsetWidth;
    </script>
    </body>
    Last edited by freedom_razor; 03-24-2009 at 03:48 PM. Reason: itsallkizza wrote 5 times more than me in half the time...

  • #5
    Senior Coder
    Join Date
    Oct 2008
    Location
    Long Beach
    Posts
    1,196
    Thanks
    36
    Thanked 164 Times in 164 Posts
    In response to your PM...
    You can do something like this (changes in red):
    Code:
    <script type="text/javascript">
    // <![CDATA[
    var img_id_pre = "img";
    var total_num_imgs = 100;
    
    // ImageCollection JS Class
    function ImageCollection()
    	{
    	this.images = new Array();
    	this.current_index = 0;
    	this.addImages = function(ids)
    		{
    		if (typeof(id) == "string") id = [ids];
    		for (var i=0;i<ids.length;i++) this.images.push(new MyImage(ids[i]));
    		}
    	this.next = function()
    		{
    		return (this.images[++this.current_index]);
    		}
    	}
    
    // MyImage JS Class
    function MyImage(id)
    	{
    	this.ref_id = id;
    	this.div = document.getElementById("id");
    	}
    
    window.onload = function()
    	{
    	my_image_collection = new ImageCollection();
    
    	var images_to_add = new Array();
    	for (var i=0;i<total_num_imgs;i++) images_to_add[images_to_add.length] = img_id_pre+i;
    	my_image_collection.addImages(images_to_add);
    
    	alert(my_image_collection.next());
    	}
    
    // ]]>
    </script>
    Or this:
    Code:
    <script type="text/javascript">
    // <![CDATA[
    var img_id_pre = "img";
    var total_num_imgs = 100;
    
    // ImageCollection JS Class
    function ImageCollection()
    	{
    	this.images = new Array();
    	this.current_index = 0;
    	this.addImages = function(ids)
    		{
    		if (typeof(id) == "string") id = [ids];
    		for (var i=0;i<ids.length;i++) this.images.push(new MyImage(ids[i]));
    		}
    	this.next = function()
    		{
    		return (this.images[++this.current_index]);
    		}
    	}
    
    // MyImage JS Class
    function MyImage(id)
    	{
    	this.ref_id = id;
    	this.div = document.getElementById("id");
    	}
    
    window.onload = function()
    	{
    	my_image_collection = new ImageCollection();
    
    	for (var i=0;i<total_num_imgs;i++) my_image_collection.addImages(img_id_pre+i);
    
    	alert(my_image_collection.next());
    	}
    
    // ]]>
    </script>
    Feel free to e-mail me if I forget to respond ;)
    ohsosexybrit@gmail.com

  • #6
    Kor
    Kor is offline
    Red Devil Mod Kor's Avatar
    Join Date
    Apr 2003
    Location
    Bucharest, ROMANIA
    Posts
    8,478
    Thanks
    58
    Thanked 379 Times in 375 Posts
    retired1

    In response to your PM (by the way... don't use PM for matters which might be interesting for the others as well)

    You said:
    Quote Originally Posted by retired1
    ...
    I am not familiar with the type of loop in your suggestion; in particular, how the loop stops. When I replace everything in the outer braces {} with an alert statement and the value of i, it continues forever, incrementing i each time. How is it supposed to stop?

    It is also a question of mine whether the
    “while (d=document...” should be written as
    “while (d==document...”
    ...
    Here's a detailed example of how that kind of while loop works:
    Code:
    var radio_buttons=theform['radiogroup_common_name'], i=0, r;
    while(r=radio_buttons[i++]){
    ... statement ...
    }
    contains 5 distinct operations:
    1. assignment: the variable r gets the value of the radio_buttons[i]. That value may be the reference of the object (which is evaluated by the conditioner as a Boolean true), or a Boolean false, if the object does not exists (if the radio_buttons[i++] overpasses the collection's length)
    2. Boolean conditioner (check if the variable r is defined/true, undefined/false)
    if the step 2 is passed, the next 3 steps comes (otherwise the loop stops)
    3. increment the indent (only at this moment i becomes i+1)
    4. runs the statement
    5. returns to the while conditioner and starts a new loop, based now on the i+1 value increment

    As you can see, the incrementation is made after the assignment, so that, inside the statement, the variable r has, lets say on first loop, the value radio_buttons[0], but the variable i has the value changed in i+1, that means 1. That means: if you need to use the index of the collection's element, but inside of that kind of loop, you should consider it as i-1.

    By short, behind of what you may think it is a single assignment
    Code:
    r=radio_buttons[i++];
    lays, in fact, two elementary, sequentially basic assignments:
    Code:
    r=radio_buttons[i];
    i++;
    =================
    See an example:
    Code:
    var myArray=['a','b','c','d'], arr, i=0;
    arr=myArray[i++];
    alert(arr+'|'+i);//alerts a|1
    ...it is the same as:
    Code:
    var myArray=['a','b','c','d'], arr, i=0;
    arr=myArray[i];
    i++;
    alert(arr+'|'+i);//alerts a|1
    Last edited by Kor; 03-26-2009 at 09:08 PM.
    KOR
    Offshore programming
    -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*

  • Users who have thanked Kor for this post:

    retired1 (03-31-2009)

  • #7
    New to the CF scene
    Join Date
    Mar 2009
    Location
    State College, PA, USA
    Posts
    3
    Thanks
    2
    Thanked 0 Times in 0 Posts

    Simplifying a large number of similar object definitions

    Kor,

    Thanks for taking the trouble to explain the details of this kind of while statement, of which I had been unfamiliar. I had no trouble using your suggestion with arrays (setting d=consecutive array elements); it seemed to work fine and continued to the point an array element was undefined. That has some nice applications where you don’t know how many consecutive array elements are going to be defined or don’t care to input the number.

    However, for use with objects, I had trouble making your suggestion work. After considerable trial and error, I found the coding below, almost identical to yours, does just what I wanted (although even it could, perhaps, be simplified):

    Code:
     var Img0 =
     	{init:function()
     		{    var i = 0, d;
     		     while(d = document.getElementById('img'+(i++)))
     		 	    {window['Img'+(i-1)] = {init:function() {} };
     			     window['Img'+(i-1)].div = d;
     			    };
     		     continue_on();
     		}
     	 };
    Img0.init is executed when all html is loaded; function “continue_on” just goes on to the next part of the program.

    Your suggested method is much appreciated.

    retired1

  • #8
    Senior Coder
    Join Date
    Oct 2008
    Location
    Long Beach
    Posts
    1,196
    Thanks
    36
    Thanked 164 Times in 164 Posts
    If you're looking for semantic object-oriented coding, I'd suggest you take another look at the code I spent the time writing up for you.
    Feel free to e-mail me if I forget to respond ;)
    ohsosexybrit@gmail.com

  • #9
    New to the CF scene
    Join Date
    Mar 2009
    Location
    State College, PA, USA
    Posts
    3
    Thanks
    2
    Thanked 0 Times in 0 Posts

    Simplifying a large number of similar object definitions

    itsallkizza,

    I am having difficulty incorporating your code into my existing program. Specifically, I need to assign a unique zIndex to each of my images and normally do this with a loop containing statements of form:
    objName.div.style.zIndex = assigned value;

    Using your nomenclature, what would be objName?

    Thanks.

  • #10
    Senior Coder
    Join Date
    Oct 2008
    Location
    Long Beach
    Posts
    1,196
    Thanks
    36
    Thanked 164 Times in 164 Posts
    If you need to assign them a z-index as you add them you can do so like this:
    Code:
    var img_id_pre = "img";
    var total_num_imgs = 100;
    
    // ImageCollection JS Class
    function ImageCollection()
    	{
    	this.images = new Array();
    	this.current_index = 0;
    	this.addImages = function(ids)
    		{
    		if (typeof(ids) == "string") ids = [ids];
    		for (var i=0;i<ids.length;i++) this.images.push(new MyImage(ids[i]));
    		}
    	this.next = function()
    		{
    		return (this.images[++this.current_index]);
    		}
    	}
    
    // MyImage JS Class
    function MyImage(id)
    	{
    	this.ref_id = id;
    	this.div = document.getElementById("id");
    	}
    
    window.onload = function()
    	{
    	my_image_collection = new ImageCollection();
    
    	for (var i=0;i<total_num_imgs;i++)
    		{
    		my_image_collection.addImages(img_id_pre+i);
    		my_image_collection.images[my_image_collection.images.length-1].div.style.zIndex = i;
    		}
    
    	alert(my_image_collection.next());
    	}
    Or you can run through them afterward giving them a specific index of your choice, or assigning them a z-index as an inverse of the order you added them to the array (not sure what you need exactly):
    Code:
    var img_id_pre = "img";
    var total_num_imgs = 100;
    
    // ImageCollection JS Class
    function ImageCollection()
    	{
    	this.images = new Array();
    	this.current_index = 0;
    	this.addImages = function(ids)
    		{
    		if (typeof(ids) == "string") ids = [ids];
    		for (var i=0;i<ids.length;i++) this.images.push(new MyImage(ids[i]));
    		}
    	this.next = function()
    		{
    		return (this.images[++this.current_index]);
    		}
    	}
    
    // MyImage JS Class
    function MyImage(id)
    	{
    	this.ref_id = id;
    	this.div = document.getElementById("id");
    	}
    
    window.onload = function()
    	{
    	my_image_collection = new ImageCollection();
    
    	for (var i=0;i<total_num_imgs;i++) my_image_collection.addImages(img_id_pre+i);
    	// this gives all your new images a zIndex of 10, they will then appear (in relation to themselves) in the order they are coded in html
    	for (var i=0;i<my_image_collection.images.length;i++) my_image_collection.images[i].div.style.zIndex = 10;
    
    	alert(my_image_collection.next());
    	}
    Last edited by itsallkizza; 04-08-2009 at 10:06 PM.
    Feel free to e-mail me if I forget to respond ;)
    ohsosexybrit@gmail.com

  • Users who have thanked itsallkizza for this post:

    retired1 (04-08-2009)


  •  

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •