PDA

View Full Version : problem with generating layers using for loop! plz help!


shivboy
11-01-2002, 05:50 AM
hi,
i am using the following code to create cross-browser objects. its fine if i want to instantiate and create a few layers...but what if i want to create say 30 layers (with same style)? i ran a for... loop but instead of creating layers it simply wrote the whole code on the page. why so? im posting the code below, plz help me with it. thanx.

<html>
<head>
<title></title>
<style>
.oStyle {position:absolute;visibility:visible;}
</style>
<script language="JavaScript">
<!--
/////////////////////////////////////////DETECTING BROWSER TYPE\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

function browserSniff()
{
this.ver = navigator.appVersion; //Cheking for browser version
this.agent = navigator.userAgent; //Checking for browser type
this.dom = document.getElementById?1:0; //Checking if IE5+ & NS6+
this.opera5 = this.agent.indexOf("Opera 5")>-1; //Opera detection
this.ie5 = (this.ver.indexOf("MSIE 5")>-1 && this.dom && !this.opera5)?1:0; //Checking if IE5
this.ie6 = (this.ver.indexOf("MSIE 6")>-1 && this.dom && !this.opera5)?1:0; //Checking if IE6
this.ie4 = (document.all && !this.dom && !this.opera5)?1:0; //Checking if IE4
this.ie = this.ie4||this.ie5||this.ie6; //One common variable for IE detection
this.mac = this.agent.indexOf("Mac")>-1; //If IE for Mac
this.ns6 = (this.dom && parseInt(this.ver) >= 5) ?1:0; //If NS6
this.ns4 = (document.layers && !this.dom)?1:0; //If NS4
this.bs = (this.ie6||this.ie5||this.ie4||this.ns4||this.ns6||this.opera5); //Assigning browser sniffed to variable bs.
return this;
}

// Generating a simple browser sniffing object bs
var bs = new browserSniff();

function layerCreate(name,pos,top,left,t,r,b,l,visibility,color,z)
{
if(bs.dom)
{
this.obj = document.getElementById(name).style;
this.obj.position = pos;
this.obj.top = top;
this.obj.left = left;
this.obj.height = b;
this.obj.width = r;
//this.obj.clip = "rect("+t+"px,"+r+"px,"+b+"px,"+l+"px)";
this.obj.backgroundColor = color;
this.obj.vis = visibility;
this.obj.zIndex = z;
return this.obj;
}
else if(bs.ie4)
{
this.obj = document.all[name].style;
this.obj.position = pos;
this.obj.top = top;
this.obj.left = left;
this.obj.height = b;
this.obj.width = r;
this.obj.backgroundColor = color;
this.obj.vis = visibility;
this.obj.zIndex = z;
return this.obj;
}
else if(bs.ns4)
{
this.obj = document.layers[name];
this.obj.position = pos;
this.obj.top = top;
this.obj.left = left;
this.obj.clip.top = t;
this.obj.clip.right = r;
this.obj.clip.bottom = b;
this.obj.clip.left = l;
this.obj.bgColor = color;
this.obj.vis = visibility;
this.obj.zIndex = z;
return this.obj;
}
}

var cOff = "#5D5D5D";
var cOn = "#FF6600";
var pageW,pageH;


function pageInit()
{
if(bs.ns4||bs.ns6)
{
pageW = innerWidth;
pageH = innerHeight;
}
else if(bs.ie4||bs.ie5||bs.ie6)
{
pageW = document.body.clientWidth;
pageH = document.body.clientHeight;
}
var p = 5;
oDiv = new layerCreate('sDiv','absolute',pageH/2-250,pageW/2-300,0,600,500,0,'visible',cOff,0);
for(i=0;i<30;i++)
{
document.write("oDiv"+i+" = new layerCreate('div"+i+"','absolute',,parseInt(oDiv.top)+5,parseInt(oDiv.left)+"+p+",0,14,14,0,'visible',cOn,2);");
p += 15;
}
}
onload=pageInit;
//--></script>
</head>
<body bgcolor="black">
<div id="sDiv" class="oStyle">
</div>
<div id="div0" class="oStyle">
<span></span>
</div>
<div id="div1" class="oStyle">
<span></span>
</div>
<div id="div2" class="oStyle">
<span></span>
</div>
<div id="div3" class="oStyle">
<span></span>
</div>
<div id="div4" class="oStyle">
<span></span>
</div>
<div id="div5" class="oStyle">
<span></span>
</div>
<div id="div6" class="oStyle">
<span></span>
</div>
<div id="div7" class="oStyle">
<span></span>
</div>
<div id="div8" class="oStyle">
<span></span>
</div>
<div id="div9" class="oStyle">
<span></span>
</div>
<div id="div10" class="oStyle">
<span></span>
</div>
<div id="div11" class="oStyle">
<span></span>
</div>
<div id="div12" class="oStyle">
<span></span>
</div>
<div id="div13" class="oStyle">
<span></span>
</div>
<div id="div14" class="oStyle">
<span></span>
</div>
<div id="div15" class="oStyle">
<span></span>
</div>
<div id="div16" class="oStyle">
<span></span>
</div>
<div id="div17" class="oStyle">
<span></span>
</div>
<div id="div18" class="oStyle">
<span></span>
</div>
<div id="div19" class="oStyle">
<span></span>
</div>
<div id="div20" class="oStyle">
<span></span>
</div>
<div id="div21" class="oStyle">
<span></span>
</div>
<div id="div22" class="oStyle">
<span></span>
</div>
<div id="div23" class="oStyle">
<span></span>
</div>
<div id="div24" class="oStyle">
<span></span>
</div>
<div id="div25" class="oStyle">
<span></span>
</div>
<div id="div26" class="oStyle">
<span></span>
</div>
<div id="div27" class="oStyle">
<span></span>
</div>
<div id="div28" class="oStyle">
<span></span>
</div>
<div id="div29" class="oStyle">
<span></span>
</div>
<div id="div30" class="oStyle">
<span></span>
</div>
</body>
</html>

beetle
11-01-2002, 02:47 PM
Hmmm, interesting. First thing I see wrong is what leads to the other problems. You are misusing the constructor function layerCreate. You call it just fine...but you don't really create a layer with it. Instead, you seem to just reference the style for a given DIV and modify it, and then return that style which is NOT right for a constructor. There should be NO return value.

2nd...Why are you using a document.write line to call your function within the loop? I don't get that part...oDivSet = new layerCreate('div'+i,'absolute',parseInt(oDiv.top)+5,parseInt(oDiv.left)+p,0,14,14,0,'visible',cOn,2) ;would work just fine...you don't need a new variable for each layer that you set...the same one can be reused...

Ok, besides all of what I've said above, I don't see any real point doing this as an object anyway. You could just as easily use a regular function.

Note: You make the same strange coding in your browser sniffer constructor. What are these lines supposed to do?this.bs = (this.ie6||this.ie5||this.ie4||this.ns4||this.ns6||this.opera5); //Assigning browser sniffed to variable bs.
return this; this.bs gives your object thes property 'bs' that will have a useless value of 'true'. I'm not sure what you'd do with it. return this;, as I mentioned before, is not how constructor functions work. There is no need to return anything, as the objects properties are already set by your use of the this keyword

shivboy
11-01-2002, 07:15 PM
hi beetle,

thanx a ton man! it worked like anything. could elaborate something for me plz? u say that a constructor function should NOT have a return value, why? furthermore, i have one more query and that is now i have create 30 layers, but what if i want to put those layers into an array? how do i do that? this is one problem ive not been able to solve at all! i would be really grateful if u wud help me with this. thanx again!

shivboy

beetle
11-01-2002, 07:41 PM
Ok, a tiny lesson in javascript objects (on which, I am nowhere near an expert)

When you have a constructor function, that is, a function that creates an object and is called with the new keyword, you don't need to return anything. Being that it is assigned with the new keyword, all the properties and methods are attached within to the object variable by said constructor function. A return value from a function is only necessary when you want to assign the return value to a variable. For example, the built-in function parseInt();var num = "3";
var number = parseInt(num);The return value from parseInt() is an integer value extracted from the string value (num) that we passed to it. The variable number receives that return value. Now, with a simple constructor functionfunction Entry(fname, lname, phone, email) {
this.first = fname;
this.last = lname;
this.full = fName + " " + lName;
this.phone = phone;
this.email = email;
}for creating addressbook entry objects, all we need to do to make the object, is assign it to a variable with the new keywordvar user = new Entry('John','Doe','123-456-7890','john@doe.com');That's it! Our entry object, user now exists and has all the properties we assigned. Now, let's say we wanted an additional property, but not one that existed for EVERY instance of the Entry object, say, the a display name (Last, First). We can use an object function (commonly called a 'method') for this.function Entry(fname, lname, phone, email) {
this.first = fname;
this.last = lname;
this.full = fName + " " + lName;
this.phone = phone;
this.email = email;
this.getDisplayName = function () {
return this.last + ", " + this.first;
}
}So, now assume we created our 'user' entry object using this verson of the constructor, we can now easily get the display name and assign it to anything, even another property of the object if we wish to!user.display = user.getDisplayName();Everything above is a real simple example, but I think you should be able to undertand what's going on....

shivboy
11-02-2002, 07:31 AM
hi beetle,
thanx a ton for this explanation. it was of great help. ive already printed it out for me. i commented the line return this.obj so it generated an error and all the visible layers disappeared. why did this happen? i mean is this some bug with IE & NS or maybe JavaScript doesn't follow strictly the rules of object creation?

one more thing, i asked u abt in the previous post also, i tried to create an array of layers, using this minor alteration to the code:

var p =3;
var oDivSet = new Array();
for(i=0;i<85;i++)
{
oDivSet[i] = new layerCreate('div'+i,'absolute',parseInt(oDiv.top)+5,parseInt(oDiv.left)+p,0,5,5,0,'visible',cOn,2);
p += 7;
}

but it didnt work. when i used the slert function to see the value of oDivSet[4] the output was [object] . is there something wrong that im doing? i hope im not bothering too much with all these questions :)

beetle
11-02-2002, 04:31 PM
Well, the problem is that your layerCreate function isn't creating layers. It's setting the style for exising DIV elements to make them layers. Like I mentioned a couple posts up, you don't need a data object constructor to handle this, and is actually a misuse of the construct.

Let me know a bit more about exactly what you are trying to accomplish...when you say "create an array of layers" do you want the array to actually contain object references? Or just an array of the layer names and/or ids? If you are referring to the earlier, you may have trouble making this completely browser compatible (read: NS4)

Or, do you really want to just set their styles, like you are trying to do now, with the DIV elements aready existing in the HTML?

shivboy
11-02-2002, 09:32 PM
hi beetle,
first let me thank u for being so helpful with all this. its really very nice of u to take out time and help. seriously!

see i want to create layers and alter their size, position and color as per my wish. so instead of specifically pointing towards each and every div individually, i want to create an array of div names which could help me change their properties. like say, in the function layerCreate i wud add a line :

this.size = changeSize;

where changeSize is a function which alters the size of the layer taking height and width as parameters, which i can change saying :

if(a==1)
{
div1.size(100,100);
}
else
{ d1.doSomethingElse;}

this is what i want to create an array for. suppose i have an array say, divArray,which contains all the div names so created, i can say:

divArray[4].size(250,50);

i may want to run a for loop to access more than one divs in one go and change their size. that actually is the primary motive.

can this be done without compromising on the feature of being cross-browser of the code? thanx again for being so helpful.