...

View Full Version : How to call array images from <img src=” ”> ?



lllusion
12-21-2006, 12:45 PM
Problem:
There are X number of images in a folder. I want to have xhtml/css code that does NOT need to be modified when the image file name changes.

Thus, <img src=”image[0]” /> (or whatever the name/code needs to be here), and all further images on the page (i.e. - <img src=”image[1]” />) must not have to be edited. Instead, I want to edit a separate image.js file stored in folder ‘media’ at the root of my site.

Question:
How does one call those images from within the img tag?

Note: I do NOT want to preload these images and therefore have created an array in the images.js file.


image = new Array();
image[0] ='../images/dog.jpg'
image[1] ='../images/car.jpg'
image[2] ='../images/home.jpg'
image[3] ='../images/girl.jpg'
image[4] ='../images/boy.jpg'
image[5] ='../images/cookies.jpg'
image[6] ='../images/plate.jpg'
image[7] ='../images/santa.jpg'
image[8] ='../images/bunny.jpg'
image[9] ='../images/turkey.jpg'
image[10] ='../images/presents.jpg'
image[11] ='../images/food.jpg'
image[12] ='../images/airplane.jpg'
index = Math.floor(Math.random() * image.length);


Question2:
How would the solution differ if the image source were being passed to a swapImage function, i.e.- onmousedown="MM_swapImage('target','','images/dog.jpg',1)" ?

Arbitrator
12-21-2006, 06:48 PM
Q1: Perhaps something like this? It creates a new image with the appropriate attributes and inserts it at the location in the document that you specify. All changes are made through the script rather than via XHTML or CSS. If you just need to change attributes of an existing image, well, that’s basically demonstrated below as well. If you used code like the below, you’d probably want to combine the four arrays.

for (var i = 0; i < image.length; i++) {
var img = document.createElement("img");
img.alt = altText[i];
img.width = width[i];
img.height = height[i];
img.src = image[i];
element.appendChild(img);
}

lllusion
12-21-2006, 07:45 PM
Hmm, forgive my scripting ignorance. However, it doesn't look like this is what I'm looking for.

I don't need to make changes the images themselves. I just want to change which images are used on the webpage by manually changing the image names in the image.js file, thereby leaving the xhtml code unchanged.

I'll manually upload new image files then quickly edit the image array (in the image.js file) by manually changing out the names of the files loaded into the array (i.e.- cat.jpg instead of dog.jpg, & bicycle.jpg instead of car.jpg). Once done the img src tags just keeps calling image0, image1, image3 never knowing that they are now completely different images.

The point is that it's easier to change img src file names in one short text file than going through an html doc and changing them.

Arbitrator
12-22-2006, 01:22 AM
Based on your statements, it looks like the code that I provided is what you would need to do what you describe. You say that “[you] don’t need to make changes to the images themselves” yet you want to swap the old images for new ones which does require changing the images themselves.

Specifically, you need to change the image’s src attribute to point to the new image. As a consequence, you most likely then need to change the alt attribute (required in XHTML) which provides a textual alternative when the image fails to display. Lastly, if the images vary in size, you may want to indicate the new image’s dimensions explicitly so that (A) the page and images appear to load more quickly and (B) your layout isn’t negatively affected should the images fail to load; that requires altering the width and height attributes/properties of the image.

The example script I provided loops through your array, creates new image elements with information drawn from that array, and then appends those image elements to the document source, thus resulting in them being rendered.

My guess though is that you actually want to edit the XHTML file first, despite claims to the contrary. Basically, you want dummy image elements that have their intended src attribute value supplied via JavaScript. Thus:

<img alt="" src="" onload="this.src = image[0];"/>

However, that’s not semantic, results in nothing being displayed if the user has JavaScript disabled, results in clutter in the XHTML source, and is hardly necessary since the image can be both created and added to the document’s source via JavaScript alone. Note that “onload...” is in red because that code is invalid; you would need to associate the new image URIs via a method that isn’t inline, such as window.onload.

Of course, I may have it all wrong due to lack of information; in that case, you need to provide more details to get the information that you seek.

Personally, if you’re only doing this to save yourself some effort editing one document (I can only assume), this is kind of pointless since writing the script will require more effort, increase the document’s effective file size, increase the code that must be sifted through, and decrease document accessibility.

lllusion
12-23-2006, 09:51 AM
Again, please forgive my coding ignorance. The goal has been to swap out images, with the size & alt being of little concern in this particular context. However, I see now that having them referenced as well would be beneficial.

I'm still uncertain how to incorporate your suggested script since I'm used to seeing something like:
function FuncName() {
..jscript stuff..
}

...and then calling it from the xhtml via something like:
onmousedown="FuncName('x','y','z',1)"

My hope has been to write the xhtml in such a way that the img src references the image in the array directly so that the only editing that ever gets done is to the array script.


...since the image can be both created and added to the document’s source via JavaScript alone.
Do you mean by something like this?
<script>document.write("<img SRC="+"images/"+image[0]+"/>");</script>
<script>document.write("<img SRC="+"images/"+image[1]+"/>");</script>
<script>document.write("<img SRC="+"images/"+image[2]+"/>");</script>

This solves one problem in that the xhtml never has to get edited, only the file containing the array definitions.

However, two problems and one issue remain:
1) How can id, class, alt and size attributes be included in the above img src tag?
2) How can this be used when the image source is passed to another script? i.e.- onmousedown="MM_swapImage('target','','images/image01.jpg',1)"
3) Is it possible to put the document.write line in an external script file and call it from the xhtml instead of having script tags in the xhtml itself?

Thanks for you help and patience!

Arbitrator
12-24-2006, 12:48 AM
1) How can id, class, alt and size attributes be included in the above img src tag?Okay, you don’t seem to understand the explanations or to be very familiar with JavaScript, so here’s an example: http://jsg.byethost4.com/demos/CF 103490 Demo.html. The source is provided at the end of this post for reference purposes.


2) How can this be used when the image source is passed to another script? i.e.- onmousedown="MM_swapImage('target','','images/image01.jpg',1)"(A) Don’t use inline script for your roll‐overs. Move all of that to a script file. (B) Access the data as variables. You’ve already assigned the array containing the data to a variable so you can just access the array to get the information.


<script>document.write("<img SRC="+"images/"+image[0]+"/>");</script>
<script>document.write("<img SRC="+"images/"+image[1]+"/>");</script>
<script>document.write("<img SRC="+"images/"+image[2]+"/>");</script>

3) Is it possible to put the document.write line in an external script file and call it from the xhtml instead of having script tags in the xhtml itself?Don’t use document.write(). It’s bad practice and it’s illegal in XHTML anyway. Additionally, all attribute names in XHTML are in lowercase, so “SRC” is invalid. Finally, script elements require type attributes.


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<meta name="Author" content="Patrick Garies"/>
<title>CF 103490 Demo</title>

<style type="text/css">
* {
margin: 0;
}
html, body, div {
height: 100%;
font: 25px "Palatino Linotype", Palatino, serif;
text-align: center;
}
div {
float: left;
width: 33.3%;
}
*#middle {
background-color: #222;
color: white;
}
h1, img {
display: block;
margin: 1em auto;
}
</style>

<script type="text/javascript">
var images = new Array();
images[0] = new Array("Article A", "article_a.png");
images[1] = new Array("Article B", "article_b.png");
images[2] = new Array("Article C", "article_c.png");
images[3] = new Array("Article D", "article_d.png");
images[4] = new Array("Article E", "article_e.png");
images[5] = new Array("Article F", "article_f.png");
window.onload = function() {
for (var i = 0; i < images.length; i++) {
var image = document.createElement("img");
image.alt = images[i][0];
image.width = "150";
image.height = "150";
image.src = images[i][1];
var j = i;
if (j > 2) j = i - 3;
document.getElementsByTagName("div")[j].appendChild(image);
}
}
</script>

</head>
<body>

<div>
<h1>Column 1</h1>
</div>
<div id="middle">
<h1>Column 2</h1>
</div>
<div>
<h1>Column 3</h1>
</div>

</body>
</html>

lllusion
12-24-2006, 10:50 AM
Thank you, Arbitrator.
I apologize if I seem a little slow or dense. As you have surmised, I have zero JavaScript education. Your patience and extended explanations are appreciated.

Let’s see if I understand what you’ve given me.


(A) Don’t use inline script for your rollovers. Move all of that to a script file. (B) Access the data as variables. You’ve already assigned the array containing the data to a variable so you can just access the array to get the information.
Ok, I didn’t make the connection between accessing as variables vs. inline scripting, which is “not semantic, can cause display problems, results in clutter, and unnecessary.”

Looking at your new script:
I included the width and height attributes in the same array using the following modification, which allows for variable width and height properties as you previously pointed out. I also have moved the script into an imgList.js file and referenced it from the xhtml header.



var images = new Array();
images[0] = new Array("Article A", "g04/article_a.png", "150", "150");
images[1] = new Array("Article B", "g04/article_b.png", "150", "150");
images[2] = new Array("Article C", "g04/article_c.png", "150", "150");
images[3] = new Array("Article D", "g04/article_d.png", "150", "150");
images[4] = new Array("Article E", "g04/article_e.png", "150", "150");
images[5] = new Array("Article F", "g04/article_f.png", "150", "150");
window.onload = function() {
for (var i = 0; i < images.length; i++) {
var image = document.createElement("img");
image.alt = images[i][0];
image.src = images[i][1];
image.width = images[i][2];
image.height = images[i][3];
var j = i;
if (j > 2) j = i - 3;
document.getElementsByTagName("div")[j].appendChild(image);
}
}


Does this array pre-load all the images? The concern is that I don’t want the user to wait for 9 to 18 60KB images to load, but would rather have each one load as needed.

Other things that I do not understand:
1. It appeared, at first, that all the div tags were getting parsed from top to bottom, each getting a new img element. But when I but when I attempt to add more images to the array to display more images in each column there’s a scripting error.

2. Likewise, when I create a six column layout only the first three columns get parsed unless the j > 2 is changed to j > 5 (or greater). And if j > 4 then column 3 gets two images while all the rest get 1. I’m really at a loss here.

3. IIUC, in this example all div tags (well, the first X number based on the 'j >' statement will be given an img tag. What if only some of the divs should contain images? How can these specific areas be targeted?

Thanks again for your help!

Arbitrator
12-25-2006, 03:49 AM
As you have surmised, I have zero JavaScript education.Then how is this supposed to make updating images easier than updating an XHTML source? You’ll either need to edit the source or learn JavaScript. A good place to start learning is here (http://www.quirksmode.org/index.html?/dom/w3c_core.html).


Ok, I didn’t make the connection between accessing as variables vs. inline scripting, which is “not semantic, can cause display problems, results in clutter, and unnecessary.”Putting parts of your scripts inline makes it harder to tell what your scripts are doing since all of the script data is not in one place. Part of it might be in the head of the document (embedded), part of it might be in the body (inline), and part of it might be in a separate *.js file (external). I simply meant to keep all of your script information in one place as opposed to your proposal of using something like an (inline) event attribute (onmousedown) coupled with a separate file. It makes it easier to maintain your scripts.


Does this array pre-load all the images? The concern is that I don’t want the user to wait for 9 to 18 60KB images to load, but would rather have each one load as needed.None of the images are preloaded; each image is called on‐demand. Specifically, each image begins loading once its added to the page via appendChild().


1. It appeared, at first, that all the div tags were getting parsed from top to bottom, each getting a new img element. But when I but when I attempt to add more images to the array to display more images in each column there’s a scripting error.

2. Likewise, when I create a six column layout only the first three columns get parsed unless the j > 2 is changed to j > 5 (or greater). And if j > 4 then column 3 gets two images while all the rest get 1. I’m really at a loss here.That script is specifically designed to load exactly six images into exactly three div elements. It sends the images into div nodes 0, 1, and 2; after that point, “i” is greater than two, so the if statement is triggered and “i” has three subtracted from it, resulting in the images being sent into div nodes 0 (3−3), 1 (4−3), and 2 (5−3) again.

The script is designed for that page. It’s a demo that shows you how to do (in general) what I was explaining. You’ll need to write your own script to suit your own page(s).


3. IIUC, in this example all div tags (well, the first X number based on the 'j >' statement will be given an img tag. What if only some of the divs should contain images? How can these specific areas be targeted?!Use precision reference methods or assign the elements you wish to insert the images into an id attribute so that you can use getElementById() to target them.

lllusion
12-25-2006, 01:28 PM
Then how is this supposed to make updating images easier than updating an XHTML source? You’ll either need to edit the source or learn JavaScript. A good place to start learning is here (http://www.quirksmode.org/index.html?/dom/w3c_core.html).It's easier to open and change out image names in a short imgList.js file that has all the names of the images listed line by line at the top of the file than to scan through an xhtml file. This is especially true if it's not me who needs to replace the images but rather someone else who understands neither xhtml nor JavaScript.


None of the images are preloaded; each image is called on demand. Specifically, each image begins loading once its added to the page via appendChild(). You previously said that it was both bad practice and illegal to use document.write(). The only other options are then document.createElement() and Node.appendChild(), correct? (And for the sake of keeping script information together this should be done in a separate file or in the header.)


That script is specifically designed to load exactly six images into exactly three div elements. ...Thanks for explaining.


Use precision reference methods or assign the elements you wish to insert the images into an id attribute so that you can use getElementById() to target them.The getElementById() I understand now (bummer that there's no getElementByClass since that seems like it would make life much easier), but as far as how to write a script to do with it exactly what I want (i.e. createElement or appendChild), or FTM what precision reference methods are, I'll have to do a bunch more reading.

lllusion
12-25-2006, 02:18 PM
...And thanks for the link to "W3C DOM Compatibility - Core"

Arbitrator
12-26-2006, 12:44 AM
You previously said that it was both bad practice and illegal to use document.write(). The only other options are then document.createElement() and Node.appendChild(), correct? (And for the sake of keeping script information together this should be done in a separate file or in the header.)There are other methods of inserting elements such as insertBefore() which puts an element just before another element and replaceChild() which replaces a specific child element of some parent element. I believe there are also other specific methods for elements that have certain mandatory structures such as tables and select lists, but I haven’t experimented with those yet.


The getElementById() I understand now (bummer that there's no getElementByClass since that seems like it would make life much easier), but as far as how to write a script to do with it exactly what I want (i.e. createElement or appendChild), or FTM what precision reference methods are, I'll have to do a bunch more reading.You should be able to create a behavior that targets based upon class by looping through all of the elements and testing whether the value of their class attribute matches some predetermined value. If the value does, then some part of the script would be executed.

You can also put all of the elements in a class (without assigning a class attribute) into a single container with a specific ID then loop through the elements in that container. You would use a reference like this:


document.getElementById(elementId).getElementsByTagName(elementName)

lllusion
12-28-2006, 02:48 PM
You should be able to create a behavior that targets based upon class by looping through all of the elements and testing whether the value of their class attribute matches some predetermined value. If the value does, then some part of the script would be executed.
Attempt #1: all the images end up under column 3 instead of one in each column. Why?


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="Author" content="Patrick Garies" />

<title>Load Images from Array</title>

<style type="text/css">
* {margin: 0; padding: 0; border: 0;}

html, body, div {height: 100%; font: 25px "Palatino Linotype", Palatino, serif; text-align: center;}
div {float: left; width: 33%;}

*#middle {background-color: #222; color: white;}

h1, img {display: block; margin: 1em auto;}

#dummy {position: absolute; top: 300px; left: 300px; height: 20px; width: 100px; font-size: 14px; color: #000000; background-color: yellow; border: black dotted 1px;}
</style>

<script>
var images = new Array();
images[0] = new Array("Article A", "images/article_a.png");
images[1] = new Array("Article B", "images/article_b.png");
images[2] = new Array("Article C", "images/article_c.png");
window.onload = function() {
for (var i = 0; i < images.length; i++) {
var image = document.createElement("img");
image.alt = images[i][0];
image.width = "150";
image.height = "150";
image.src = images[i][1];
var timgs=document.getElementsByTagName('a')
for (var i_tem = 0; i_tem < timgs.length; i_tem++)
if (timgs[i_tem].className=='thumbImage'){
timgs[i_tem].appendChild(image);
}
}
}
</script>
</head>

<body>

<div>
<h1>Column 1</h1>
<a href="#" class="thumbImage"></a>
</div>

<div id="middle">
<h1>Column 2</h1>
<a href="#" class="thumbImage"></a>
</div>

<div>
<h1>Column 3</h1>
<a href="#" class="thumbImage"></a>
</div>

<div id="dummy">
<a href="#">Dummy div.</a>
</div>

</body>
</html>


BTW, I realized that you used window.onload = function () instead of <body onload="demo();"> so that the xhtml would verify strict. This also keeps, as you have stated, the JavaScript out of the xhtml. However, can there be two different functions each utilizing the window.onload?

Ancora
12-28-2006, 07:53 PM
Illusion:



<script type="text/javascript">

var images =[];
images[0] = ["Article A", "images/article_a.png"];
images[1] = ["Article B", "images/article_b.png"];
images[2] = ["Article C", "images/article_c.png"];

function insertImages(){

var timgs = document.getElementsByTagName('a')
for (i=0; i<images.length; i++)
{
var image = document.createElement("img");
image.alt = images[i][0];
image.width = "150";
image.height = "150";
image.src = images[i][1];
timgs[i].className = "thumbImage";
timgs[i].appendChild(image);
}
}


function init(){

insertImages();
//nextFunction();

}

onload=init;

</script>
</head>

lllusion
12-28-2006, 09:31 PM
Thanks Ancora.

How does timgs[i].className = "thumbImage"; do an 'if' for className = "thumbImage" ? It looks like it would set all 'a' tags to the class "thumbImage". (Just like timgs[i].appendChild(image) appends/creates an image element for all 'a' tags with className="thumbImage".) ??

Thanks for the input on the function init() to load multiple functions onload.

Ancora
12-28-2006, 09:51 PM
Illusion:

You're welcome, I appreciate your courtesy.
My goodness, yes, that line is wrong.
It should be:

image.className = "thumbImage";

But, obviously, you knew that already...

Arbitrator
12-29-2006, 03:06 AM
Attempt #1: all the images end up under column 3 instead of one in each column. Why?This is because your nested for loop is first putting the image into column one, then moving the same image into column two, then finally moving that same image into the last column. If you want one copy in each column, then you need to clone that particular image element.

Here’s a revision of your code that does what I’m assuming you that you intended via cloneNode().

Note that I also added some curly brackets that were missing for the nested for loop; not sure how you managed to get away with that and not have the script throw an error. I also moved the “timgs” assignment line out of the loop since performing the same assignment over and over needlessly is inefficient. Additionally, some CSS adjustments were made since you were inserting block‐level images into inline anchor elements. Finally, I made the code valid by adding a type attribute to the script element.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<meta name="Author" content="Patrick Garies"/>
<title>Load Images from Array</title>

<style type="text/css">
* {
margin: 0;
border: 0 none;
padding: 0;
}
html, body, div {
height: 100%;
text-align: center;
font: 25px "Palatino Linotype", Palatino, serif;
}
div {
float: left;
width: 33%;
}
*#middle {
background-color: #222;
color: white;
}
*#dummy {
position: absolute;
top: 300px;
left: 300px;
width: 100px;
height: 20px;
border: 1px dotted black;
background-color: yellow;
color: black;
font-size: 14px;
}
a.thumbImage {
display: block;
width: 150px;
margin: 0 auto;
background-color: #eee;
}
*#middle a.thumbImage {
background-color: #333;
}
img {
display: block;
margin: 1em 0;
}
</style>

<script type="text/javascript">
var images = [];
images[0] = ["Article A", "article_a.png"];
images[1] = ["Article B", "article_b.png"];
images[2] = ["Article C", "article_c.png"];
window.onload = function() {
var timgs = document.getElementsByTagName("a");
for (var i = 0; i < images.length; i++) {
var image = document.createElement("img");
image.alt = images[i][0];
image.width = "150";
image.height = "150";
image.src = images[i][1];
for (var i_tem = 0; i_tem < timgs.length; i_tem++) {
if (timgs[i_tem].className == "thumbImage") {
timgs[i_tem].appendChild(image.cloneNode(false));
}
}
}
}
</script>

</head>
<body>

<div>
<h1>Column 1</h1>
<a class="thumbImage" href="#"></a>
</div>

<div id="middle">
<h1>Column 2</h1>
<a class="thumbImage" href="#"></a>
</div>

<div>
<h1>Column 3</h1>
<a class="thumbImage" href="#"></a>
</div>

<div id="dummy">
<a href="#">Dummy <code>div</code>.</a>
</div>

</body>
</html>


BTW, I realized that you used window.onload = function () instead of <body onload="demo();"> so that the xhtml would verify strict. This also keeps, as you have stated, the JavaScript out of the xhtml. However, can there be two different functions each utilizing the window.onload?I didn’t do that so that it would validate; the onload attribute is allowed in XHTML 1 Strict. If you made a common mistake and named it “onLoad” with a capital “L” then it would be invalid though since XHTML attribute names must be lowercase. I did do it to keep all script elements in one place, however.

In answer to your question, yes, this is possible and is already demonstrated in the code I wrote. I created an anonymous function and put script information inside of it. To reference numerous functions, you could do the same:


window.onload = function() {
playMusic();
changeBackgroundColor();
increaseTextSize();
// et cetera
}

You could also give the anonymous function a name instead or do what Ancora did and separate things. You could also do this using standards‐compliant JavaScript as well, but it’s not supported by Internet Explorer. Examples:


window.onload = function basic() {
playMusic();
changeBackgroundColor();
increaseTextSize();
// et cetera
}


document.defaultView.addEventListener("load", function() {
playMusic();
changeBackgroundColor();
increaseTextSize();
// et cetera
}, false);

lllusion
12-29-2006, 10:01 AM
Illusion:

You're welcome, I appreciate your courtesy.
My goodness, yes, that line is wrong.
It should be:

image.className = "thumbImage";

But, obviously, you knew that already...Actually, I didn't. Both seem to work when I test them. What I was expecting to see is if (timgs[i_tem].className == "thumbImage") as Arbitrator wrote.


This is because your nested for loop is first putting the image into column one, then moving the same image into column two, then finally moving that same image into the last column. If you want one copy in each column, then you need to clone that particular image element.

Here’s a revision of your code that does what I’m assuming you that you intended via cloneNode().I think I understand what you mean about the loop since I didn't think about the fact that the second 'for' will continue running until complete before going back up to the first 'for'. I don't get how the images get moved over and over again from one column to the next in my script.

Regardless, your new version is a fun twist I hadn't thought of. (Might just come in handy too.) However, no, I'm not wanting to put copies of all three images into each column, but rather one copy of one image in each of the three columns (Image A in column 1, Image B in column 2, Image C in column 3), which is what Ancora's code does, it's just that I don't understand how his version tests for className="thumbImage".


...Additionally, some CSS adjustments were made since you were inserting block-level images into inline anchor elements....Are you refering to a.thumbImage {display: block;}? If so, I wasn't aware that redifinition of a block level element was necessary when inserting into another block level element. If you're also refering to the proper use of universal selectors, that's not something that I've previously been introduced to (but have now looked up).

Arbitrator
12-30-2006, 09:26 AM
I don't get how the images get moved over and over again from one column to the next in my script.I meant that when you declare a new image element, you’re assigning it to a variable. You use that variable to put the image into the first column via the nested for loop. Then you use that same variable, referencing the same instance of the image you created and move it to the second column. Then you repeat it for the last column. What happens is that the instance of the image is moved from one column to the next. In order for it to appear in all columns, instead of being shoved around, you need to clone it to create multiple instances; specifically, you need one instance for each column.

After the nested for loop has completed, the main for loop is also complete. Since that image element’s instance and variable were declared inside the for loop and is local to that repetition of the loop, the instance and variables are discarded. Then, on the next repetition, the variable can be re‐declared because it’s no longer in use. An assignment to this “new” variable creates another instance of the image.


it's just that I don't understand how his version tests for className="thumbImage".Glancing at it, it doesn’t test for the class name at all. The first version simply appends a class name to the anchor elements that images are inserted in. The revision makes it so that the classes are assigned to the images instead of the anchors.

That’s unlike your last document (the one I revised) which does test for class name. I think where you went wrong there was unnecessarily adding a nested for loop since that will result in the image always going into the last anchor element, or, with my revision, into every anchor element. You probably need to create an array that contains only the anchor elements with the designated class before you run the for loop (and get rid of the nested loop).


Are you refering to a.thumbImage {display: block;}? If so, I wasn't aware that redifinition of a block level element was necessary when inserting into another block level element.Not sure what you’re talking about here since neither anchors nor images are block‐level by default, so no “red[e]finition” is going on.

I was mainly referring to your insertion of images declared as block‐level into inline level anchor elements; since block‐level elements cannot be contained inside of inline elements without poorly supported CSS2/2.1 values, that should be avoided to avoid potential problems. An example is odd behaviors exhibited when putting something like a div inside an anchor element (illegal in (X)HTML).

I would guess that if you performed such an “illegal” operation, an anonymous (CSS2.1) display: inline-block container would be generated between the image and anchor element so that things made sense and didn’t start getting buggy, but Firefox doesn’t support it and other browsers only support it with bugs.

lllusion
01-01-2007, 02:42 PM
So here's my latest attempt. It seems to work like a charm. The idea being that each anchor with className == "thumbImage" gets a child image tag with src= the next image in the array, starting with the first image in the array.

For the heck of it I also wrote the function so that a random image can be used each time an image tag is written. (If 'index' is used instead of 'j' in image.alt and image.src.) Obviously, in this case things get more interesting when the number of images in the array is larger.

Any thoughts on my solution? Anything that is illegal or could be improved? Thanks for all the help!



<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

<title>Load Images from Array</title>

<style type="text/css">
* {margin: 0; padding: 0; border: 0;}

html, body, div {height: 100%; font: 25px "Palatino Linotype", Palatino, serif; text-align: center;}
div {float: left; width: 33%;}

*#middle {background-color: #222; color: white;}

h1, img {display: block; margin: 1em auto;}

*#dummy {position: absolute; top: 300px; left: 300px; height: 20px; width: 100px; font-size: 14px; color: #000; background-color: yellow; border: black dotted 1px;}
*#dummy2 {position: absolute; top: 400px; left: 300px; height: 20px; width: 100px; font-size: 14px; color: #fff; background-color: blue; border: red solid 1px;}

a.thumbImage {
display: block;
width: 150px;
margin: 0 auto;
background-color: #eee;
}

*#middle a.thumbImage {
background-color: #333;
}
</style>
<script type="text/javascript">
var images =[];
images[0] = ["Article A", "images/article_a.png"];
images[1] = ["Article B", "images/article_b.png"];
images[2] = ["Article C", "images/article_c.png"];
images[3] = ["Article D", "images/article_d.png"];
images[4] = ["Article E", "images/article_e.png"];
images[5] = ["Article F", "images/article_f.png"];

function insertImages() {

var timgs = document.getElementsByTagName('a')
var j=0; // Sets a variable equal to the first item in the images array.
for (i=0; i<timgs.length; i++) {
if (timgs[i].className == "thumbImage") {
index = Math.floor(Math.random() * images.length);
var image = document.createElement("img");
image.alt = images[j][0]; // Uses the array counter variable. If a random image is desired then use [index] instead of [j].
image.width = "150";
image.height = "150";
image.src = images[j][1]; // Uses the array counter variable. If a random image is desired then use [index] instead of [j].
timgs[i].appendChild(image);
j++; // Advances the array counter for use next time around that an 'a' tag has a className = "thumbImage".
}
}
}

window.onload = function init(){

insertImages();
//nextFunction();
}
</script>
</head>

<body>

<div id="dummy">
<a href="#">Dummy div.</a>
</div>

<div>
<h1>Column 1</h1>
<a href="#" class="thumbImage"></a>
</div>

<div id="middle">
<h1>Column 2</h1>
<a href="#" class="thumbImage"></a>
</div>

<div>
<h1>Column 3</h1>
<a href="#" class="thumbImage"></a>
</div>

<div id="dummy2">
Dummy div2.
</div>

</body>
</html>

Arbitrator
01-02-2007, 02:03 PM
Any thoughts on my solution? Anything that is illegal or could be improved?Seems to work fine here with both “j” and “index”. Interesting to see the randomized set of images, probably because they’re so colorful.

As for illegal things, you have an unescaped less‐than sign (<) in your script. While that’s fine in HTML, it’s not in true XHTML which will read it as the start of a tag; basically, the page will throw an error and not display in true XHTML. You’re not displaying the page as true XHTML (MIME‐type application/xhtml+xml), but instead as HTML (MIME‐type text/html) so the error is not apparent, however.

Basically, you can fix that by escaping it, but not in a for loop, since that will throw a JavaScript error; so that solution is out. You can reverse the comparison by changing i<timgs.length to timgs.length>i so that the character isn’t used. Finally, you can mitigate the problem of disallowed characters altogether by (A) putting the script in an external file or (B) putting it into a marked CDATA section (the script element content is CDATA by default in HTML so that’s why this problem doesn’t occur in HTML). Things like tags and character references aren’t parsed in CDATA sections. Example:


<script type="text/javascript">
//<![CDATA[

//]]>
</script>

— or —


<script type="text/javascript">
/*<![CDATA[*/

/*]]>*/
</script>

You need to comment out the CDATA section code for when the page is viewed as HTML. Not sure why. For reference, you need to keep the same thing in mind with ampersands (&) which can be interpreted as the start of a character reference (e.g., &copy;), not just less‐than signs.

As for other issues, it’s good practice to explicitly close a line with a semi‐colon and to declare all of your variables. Examples:


var timgs = document.getElementsByTagName('a');
for (var i = 0; …) {…
var index = …;

lllusion
01-02-2007, 03:13 PM
Super! Thanks for all your help, tips, and instruction.



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum