jQuery and JavaScript Phrasebook (2014)

8. Manipulating Web Page Layout Dynamically

One of the coolest interactions that you can make with web pages is to rearrange elements on the page based on user interaction. For instance, you can make elements bigger or smaller and even change the position. Additionally, you can change the visibility of elements, hiding them when you don’t need them and revealing them when appropriate.

This chapter focuses on the methods to manipulate elements in such a way that it alters the basic layout of the page. The phrases are designed to give you usable examples that apply to an array of purposes.

Hiding and Showing Elements


$("#down").hide();
$("#up").on("click", function(){
  $("#up, #down").toggle();
  $("#leftNav").hide(); });
$("#down").on("click", function(){
  $("#up, #down").toggle();
  $("#leftNav").show(); });


A simple way of changing the look and feel of web pages is to toggle the visibility of elements. Hiding elements that are not necessary and then only showing them when they become necessary can save a lot of screen space that can be critical in a well-implemented web application.

You hide or show elements from JavaScript by setting the style.display property to "none" or to "". jQuery, in contrast, provides a much more elegant and extensible solution.

To display an element using jQuery, simply call the .show() method on the jQuery object. All items in the object set are shown. Then to hide the elements, use the .hide() method. It’s as simple as that. For example, to hide all <p> elements, you would use the following:


$("p").hide();


Then to display them again, use this:


j$("p").show();


Another valuable tool that jQuery provides is the .toggle() method. This method changes the current visibility state to the exact opposite. That means you don’t have to keep track or check to see what the visibility is for items that you simply want to toggle on and off.

The following code demonstrates changing the visibility. It hides and shows a simple popup menu. Notice that the buttons to show and hide the visibility are themselves being toggled on and off so that the appropriate button is visible to match the menu state. Figure 8.1 shows the basic look and feel of the menu:


01 <html>
02   <head>
03   <title>Python Phrasebook</title>
04   <meta charset="utf-8" />
05   <script type="text/javascript"
06     src="../js/jquery-1.9.0.min.js"></script>
07   <script>
08     var imgArr = ["bison.jpg","peak.jpg","falls.jpg"];
09     var idx = 0;
10     $(document).ready(function (){
11       $("#down").hide();
12       $("#up").on("click", function(){
13         $("#up, #down").toggle();
14         $("#leftNav").hide(); });
15       $("#down").on("click", function(){
16         $("#up, #down").toggle();
17         $("#leftNav").show(); });
18     });
19   </script>
20   <style>
21     #banner { font:bold 36px/60px "cursive, serif";
22       color:white; background-color:blue;
23       text-align:center; }
24     #bar { background-color:black; padding:3px;}
25     #leftNav {background-color:#cccccc; padding:5px;
26       width:100px; }
27     p { margin:0; margin-top:2px; border:1px solid;
28         text-align:center; border-radius:10px;
29         background-color:white; }
30   </style>
31 </head>
32   <body>
33     <div id="banner">jQuery and JavaScript</div>
34     <div id="bar"><img id="down" src="expand.png" />
35       <img id="up" src="collapse.png" /></div>
36     <div id="leftNav"><p>Option 1</p>
37       <p>Option 2</p><p>Option 3</p></div>
38   </body>
39 </html>


ch0801.html

Image

Figure 8.1 Toggling the visibility of a menu item when it is not needed using jQuery .show(), .hide(), and .toggle().

Adjusting Opacity


$("#up").on("click", function(){
  var op = parseFloat($("#photo").css("opacity"));
  if (op<1) {op += 0.2;};
  $("#photo").css("opacity", op);
});
$("#down").on("click", function(){
  var op = $("#photo").css("opacity");
  if (op>0) {op -= 0.2;};
  $("#photo").css("opacity", op);
});


Changing the opacity of elements is a great way to alter the layout of the page. Lowering the opacity value makes the item less visible, revealing any elements or background images that are behind the item.


By the way

One problem with using .hide() to hide an element is that, once applied, the element no longer takes up page space. Other flowing elements slide in to take its place. In many cases, this is the way you want it. In other instances, you may want the element to be invisible but still take up space, so set opacity to 0.


Lowering the opacity (but not to 0) can be a great way to demonstrate that elements are not currently active while still showing them. For example, I like to set menu and button elements that are not yet implemented and active to .5 opacity so that they still show up but are obviously not clickable.

The opacity CSS property controls the opacity. To make an element invisible but still take up space, set the opacity CSS property to 0. For example:


jObj.css("opacity", "0");


Then to make the element visible again, set the opacity back to 1:


jObj.css("opacity", "1");


To make an item partially visible, set the opacity between 0 and 1, such as .5. The following example creates a web page with two buttons that control the opacity of an image element. As the opacity increases, the image becomes more visible and vice versa. The click handlers for the buttons change the opacity by incrementing or decrementing the current opacity by .2. Figure 8.2 shows the opacity changes in action:


01 <html>
02   <head>
03   <title>Python Phrasebook</title>
04   <meta charset="utf-8" />
05   <script type="text/javascript"
06     src="../js/jquery-1.9.0.min.js"></script>
07   <script>
08     var imgArr = ["bison.jpg","peak.jpg","falls.jpg"];
09     var idx = 0;
10     $(document).ready(function (){
11       $("#up").on("click", function(){
12         var op = parseFloat($("#photo").css("opacity"));
13         if (op<1) {op += 0.2;};
14         $("#photo").css("opacity", op);
15       });
16       $("#down").on("click", function(){
17         var op = $("#photo").css("opacity");
18         if (op>0) {op -= 0.2;};
19         $("#photo").css("opacity", op);
20       });
21     });
22   </script>
23   <style>
24     img{ vertical-align:middle;}
25     #photo { width:300px; border:5px ridge white;
26        box-shadow: 5px 5px 5px #888888; margin:10px; }
27   </style>
28 </head>
29   <body>
30     <img id="down" src="decrease.png" />
31     <img id="photo" src="arch.jpg" />
32     <img id="up" src="increase.png" />
33   </body>
34 </html>


ch0802.html

Image

Figure 8.2 Toggling the opacity of an image using the jQuery code in ch0802.html.

Resizing Elements


$("#up").on("click", function(){
  $("#photo").width($("#photo").width()*1.2);
});
$("#down").on("click", function(){
  $("#photo").width($("#photo").width()*.8);
});


Another important aspect when dynamically working with HTML elements is the ability to get and change an element’s size. jQuery makes this simple using a set of methods attached to the jQuery object. Table 8.1 shows the methods provided by jQuery objects that allow you to get the height and width of an element.

Image

Table 8.1 jQuery Object Methods to Get and Set the Element Size


Watch out!

The height and width methods return only the size of the first element in the jQuery objects’ set. For single object sets, that is not a problem. Just keep in mind that other objects in the set may have different sizes.


To illustrate getting and setting the size of elements, consider the following sample code. This code defines a web page with a photo and two buttons. The click handlers for the buttons increase or decrease the size of the image by getting the image width using the .width() method. The image automatically resizes as the width changes in the handlers. To adjust the size, pass back a new value of width*1.2 or width*.8 into the .width() method. Figure 8.3 shows the buttons that resize the image:


01 <html>
02   <head>
03   <title>Python Phrasebook</title>
04   <meta charset="utf-8" />
05   <script type="text/javascript"
06     src="../js/jquery-1.9.0.min.js"></script>
07   <script>
08     $(document).ready(function (){
09       $("#up").on("click", function(){
10         $("#photo").width($("#photo").width()*1.2);
11       });
12       $("#down").on("click", function(){
13         $("#photo").width($("#photo").width()*.8);
14       });
15     });
16   </script>
17   <style>
18     img{ vertical-align:middle;}
19     #photo { width:300px; border:5px ridge white;
20        box-shadow: 5px 5px 5px #888888; margin:10px; }
21   </style>
22 </head>
23   <body>
24     <img id="down" src="decrease.png" />
25     <img id="photo" src="arch.jpg" />
26     <img id="up" src="increase.png" />
27   </body>
28 </html>


ch0803.html

Image

Figure 8.3 Resizing an image using the jQuery code in ch0803.html.

Repositioning Elements


$("#up").on("click", function(){
  var offset = $("#photo").offset();
  offset.top -= 10;
  $("#photo").offset(offset);
});


In addition to the size of HTML elements, you often need to determine their position. There are two different types of positions when working with HTML elements. The first type is the position relative to the full document. The second type is the position relative to the HTML element that acts as an offset parent. The element that is the offset parent depends on the position settings in CSS.

jQuery provides the .position([position]) method to get the position relative to the offset parent. The .offset([position]) method provides the position relative to the document. You can call both of these methods with no argument and return a simple object with a left and right attribute that represent the number of pixels from the left and top of document or offset parent. You can also call these methods with a simple position object with left and right attributes, in which case they set the position of the element.

For example, the following code retrieves the number of pixels from the top and the left of the document as well as the number of pixels from the top and left of the offset parent for the element with id="myElement". To get each value using a single statement I reference the top andleft attributes directly after the offset of position call:


var pixelsFromPageTop = $("#myElement").offset().top;
var pixelsFromPageLeft = $("#myElement").offset ().left;
var pixelsFromParentTop = $("#myElement").position  ().top;
var pixelsFromParentLeft = $("#myElement").position ().left;


To set the distance of that element exactly 10 pixels down and 10 pixels to the right of the top-left corner of the document, use the following statement, which defines a simple object with left and top values and passes it to the .offset() method:


$("#myElement").offset({"top":10,"left":10);


To illustrate using element position, the following code builds a web page with four control buttons and an image element. The click handlers for the buttons move the image around by getting the current offset, adjusting the top or left attribute, and then setting the offset again using the.offset() method. Figure 8.4 shows the buttons moving the image around the screen:


01 <html>
02   <head>
03   <title>Python Phrasebook</title>
04   <meta charset="utf-8" />
05   <script type="text/javascript"
06     src="../js/jquery-1.9.0.min.js"></script>
07   <script>
08     var imgArr = ["bison.jpg","peak.jpg","falls.jpg"];
09     var idx = 0;
10     $(document).ready(function (){
11       $("#up").on("click", function(){
12         var offset = $("#photo").offset();
13         offset.top -= 10;
14         $("#photo").offset(offset);
15       });
16       $("#down").on("click", function(){
17         var offset = $("#photo").offset();
18         offset.top += 10;
19         $("#photo").offset(offset);
20       });
21       $("#left").on("click", function(){
22         var offset = $("#photo").offset();
23         offset.left -= 10;
24         $("#photo").offset(offset);
25       });
26       $("#right").on("click", function(){
27         var offset = $("#photo").offset();
28         offset.left += 10;
29         $("#photo").offset(offset);
30       });
31     });
32   </script>
33   <style>
34     img{ vertical-align:middle;}
35     #photo { width:300px; border:5px ridge white;
36        box-shadow: 5px 5px 5px #888888; position: fixed; }
37   </style>
38 </head>
39   <body>
40     <div id="buttons">
41       <img id="up" src="up.png" />
42       <img id="down" src="down.png" />
43       <img id="left" src="left.png" />
44       <img id="right" src="right.png" />
45     </div>
46     <img id="photo" src="arch.jpg" />
47   </body>
48 </html>


ch0804.html

Image

Figure 8.4 Moving an image element around the screen using the jQuery code in ch0804.html.

Stacking Elements


$("img").on("click", function(){
  $("img").css("z-index", 0);
  $(this).css("z-index", 1);
});


One of the coolest interactions that you can make with web pages is to rearrange elements on top of each other based on user interaction. The idea is that HTML elements can simply be stacked on top of each other like papers on a desk. At any time, you can reveal one of the hidden or partially hidden elements and place it on top of the others.

The z-index is a CSS property that specifies the position of an HTML element with respect to other elements not vertically or horizontally, but projected out toward the user. The element with the highest z-index is displayed on top of other elements when the browser renders the page.

To get and set the z-index in jQuery, use the .css() method. For example, to get the z-index for an item, use this:


var zIndex = $("#item").css("z-index");


To set the z-index for an item to, say, 10, use the following statement:


$("#item").css("z-index", "10");


To illustrate how the z-index works, the following code generates a web page with three images. The images have fixed positioning in an overlapping fashion. When you click on one of the images, the click handler first adjusts the z-index of all items to 0 and then sets the z-index for the item clicked on to 1, thus placing it on top. This is shown in Figure 8.5:


01 <html>
02   <head>
03   <title>Python Phrasebook</title>
04   <meta charset="utf-8" />
05   <script type="text/javascript"
06     src="../js/jquery-1.9.0.min.js"></script>
07   <script>
08     var imgArr = ["bison.jpg","peak.jpg","falls.jpg"];
09     var idx = 0;
10     $(document).ready(function (){
11       $("img").on("click", function(){
12         $("img").css("z-index", 0);
13         $(this).css("z-index", 1);
14       });
15     });
16   </script>
17   <style>
18     img{ width:300px; border:5px ridge white;
19        box-shadow: 5px 5px 5px #888888; position: fixed; }
20     #photo1 { top:10px; left:20px; }
21     #photo2 { top:60px; left:60px; }
22     #photo3 { top:120px; left:120px; }
23   </style>
24 </head>
25   <body>
26     <img id="photo1" src="arch.jpg" />
27     <img id="photo2" src="beach.jpg" />
28     <img id="photo3" src="flower.jpg" />
29   </body>
30 </html>


ch0805.html

Image

Figure 8.5 Stacking elements on top of each other and reordering them using the jQuery code in ch0805.html.