All the content on the page was created manually, i.e. each element in the HTML written by hand. With JavaScript, made easier by JQuery, we can create new element nodes and put them in the document tree, even long after the page is loaded, if necessary. Content that was created by a script or program is generally referred to as procedurally-generated content.
In some cases, it is necessary to procedurally generate content: when content needs to exist only conditionally, or when a user wants to load desired content, such as more comments at the bottom of the page or a larger version of a photograph.
There are even times when it is not necessary to procedurally generate content, but doing so is highly advantageous. Specifically, when you notice that your page structure or content is following a distinct pattern, then it is often much more convenient to have JavaScript generate that content.
Procedurally generated content is typically created by the server, using a server-side language, such as ASP.NET C#, PHP, or even JavaScript using NodeJS, for example. There are multiple reasons for this:
- You have more control over the capabilities of the computer generating the code
- The end-user might have JavaScript turned off
- It is more secure to have the content-generating script on the server end, because the code cannot be seen by the end user
Automatically Generating Visible Slide Numbers
The user of the slide show might find it useful to be able to see the number of the current slide, as well as how many slides are left. We could go to the bottom of every <section> element which holds a slide, and manually type in slide numbers, but that would be neither convenient nor scalable.
Instead, let's create a function that will automatically create all of the slide numbers for us.
Approaching Code in a Modular Way
We want the slide numbers as soon as the page is done loading, so we could type the code to make this happen right at the top of our script. However, by putting the code in a separate function, it makes the code more organized and well defined.
Creating a separate function for each distinct task is a strategy in keeping our code modular, that is, arranged in an organized set of well-defined modules.
We'll now make a function designed purely for the task of generating the slide numbers.
Step 1. To define the function, after the show_current_slide function, type:
// Create slide-to-slide jump navigation
$("nav li").click(function () {
//change currentSlide to match clicked list item
currentSlide = $(this).index();
show_current_slide();
});
// Create slide numbers
function create_slide_numbers() {
}
Exiting code block
Step 2. To call the function, in the document ready event, type:
// Show the first slide
show_current_slide();
totalSlides = $(".slideshow section").length;
create_slide_numbers();
Exiting code block
Creating and Putting a Node in the Document Tree
JavaScript and JQuery both have ways to create new element nodes for placement in the document tree. As you might expect, it is much easier and more straightforward to do so with JQuery.
We can create and add a node by using JQuery's append function on a node that we match in the $() function. The argument we give to the append function is the HTML that we want to put at the end of the node matched with the $() function.
Let's get started by creating a test paragraph at the end of the first slide. We will create a variable in which to store the HTML we wish to put at the end of the first slide, and then use that variable as the argument in the append function attached to the first slide node that we got from the $() function.
Step 1. To add a test paragraph to the first slide, type:
// Create slide numbers
function create_slide_numbers() {
var slideNumP = "<p>slide number test</p>";
$(".slide" + 0).append(slideNumP);
}
Exiting code block
Step 2. Save the document and reload it in the web browser.
Step 3. To see the next slide,
Click Next Slide
NOTE: We could have put the <p> element string directly into the append function without the use of a variable. However, by using the variable, it makes the code a bit cleaner and easier to read.
Understanding Loops
If we wanted the slide number paragraph at the bottom of each slide, we could type a separate append statement for each slide. The problem with this method is that we won't always know exactly how many slides there are on the page, and even if we did, this would be a tedious and non-scalable process.
We want a way to automate appending paragraphs onto each slide. We can do this with a control structure called a loop. In programming, a loop permits the developer to have a block of code run as many times as necessary within a set condition.
Each time the block of code within a loop executes, it is called iteration. A loop will continue iterating until a predefined condition is met.
Implementing a For Loop
We intend to execute, as many times as there are slides, the statements that create and append a slide number paragraph node. The classic type of loop that assists developers in running a block of code a fixed number of times, or as many times as there are items in an array, is the for loop.
The standard format of a for loop involves defining an iterator variable, which is used to keep track of the number of iterations the loop has performed. The for loop stops iterating once the iterator has reached a predefined value.
The iterator variable definition, the conditional expression that determines if the loop continues iterating, and the way the iterator changes each iteration is all done within the parentheses after the for keyword.
Here is an example of the for loop syntax:
var fruit = ['apple', 'orange', 'grape'];
for (var i = 0; i < fruit.length; i++) {
eat(fruit[i]);
}
Exiting code block
In the parentheses after the for keyword, we have three components:
- the var i = 0 statement defines the iterator
- the i < fruit.length is the conditional expression that must be true in order for the loop to iterate again
- the i++ is the statement that will be executed at the end of each iteration.
In the previous example, i starts at 0, the first index of fruit is eaten, then i is incremented, and the condition is checked. i, now at a value of 1, is less than the fruit array's length of 3, therefore the loop iterates again, the second item in fruit is eaten, and i is incremented again. The iterator's new value of 2 is still less than fruit's length of 3, so the loop iterates again, the third item is eaten, and i iterates up to a value of 3. Since 3 is not less than 3, the loop will not iterate again, and the code will continue below.
Let's try this out now by surrounding, with a for loop, our statements that create and append a node to our first slide. We will create an iterator i and start it at 0, and set the condition to check if the iterator has reached the totalSlides variable. We will increment i every iteration.
Step 1. To wrap our function's code in a loop, type:
// Create slide numbers
function create_slide_numbers() {
for (var i = 0; i < totalSlides; i++) {
var slideNumP = "<p>slide number test</p>";
$(".slide" + 0).append(slideNumP);
}
}
Exiting code block
Referencing the Iterator
The slide number paragraph keeps getting appended to the same slide because the $() function in the for loop block keeps referencing ".slide0" every iteration. We need the selector to change each iteration of the loop to match each slide.
The only value that changes each iteration of the loop is the iterator. We will use the iterator as the index of the slide in the selector string for the $() function.
Step 1. To append the slide number paragraph to a different slide each iteration, change the code as shown:
// Create slide numbers
function create_slide_numbers() {
for (var i = 0; i < totalSlides; i++) {
var slideNumP = "<p>slide number test</p>";
$(".slide" + i.append(slideNumP);
}
}
Exiting code block
Step 2. Save the document and reload it in the web browser.
Step 3. To test the different slides,
Click the Next and Previous Slide links
Challenge Exercise 3: Fix the Text Content of the Slide Numbers
Change the function so that the text content for the slide number paragraphs reflect the page number they are on.
More specifically, make the slide number on the bottom of the first slide say "1 / 3," second slide: "2 / 3," and third slide: "3 / 3."
For a possible solution, see "Appendix 2: Challenge Exercise Solutions" on page 66.