Chapter 13

Connecting with Style: JavaScript and CSS

In This Chapter

arrow Interacting with HTML-based formatting

arrow Creating HTML style elements dynamically

arrow Moving and positioning HTML elements

arrow Developing a JavaScript-based menu

At one time, HTML pages were plain or used inconsistent tags for formatting content, such as the outdated <center> tag. Many of these tags are deprecated (no longer available) in HTML5. For example, the <center> tag is no longer available. (See http://www.w3schools.com/tags/tag_center.asp for details.) Cascading Style Sheets (CSS) provide a means for formatting HTML content in a consistent manner that works well with all newer browsers. Using CSS makes the job of the page designer and application developer easier while providing significantly more flexibility in formatting options. You can provide CSS in these ways:

check.png As part of HTML tags

check.png Within the current page

check.png As an external file

ontheweb_modern.eps Using CSS also makes it possible to support special user needs. A user can simply substitute a CSS file to meet any special requirements, such as larger fonts. In short, CSS is a big win for anyone working with HTML documents. This chapter doesn't describe CSS in detail — that would require an entire book of its own. However, you can find a great CSS tutorial on the W3Schools site at http://www.w3schools.com/css/ if you need a refresher. Using a CSS generator can also help. You can find these applications in a number of locations online, such as http://www.css3.me/ and http://css3generator.com/. To gain a fuller understanding of how CSS works with HTML, you can read HTML, XHTML & CSS For Dummies, 7th Edition by Ed Tittel and Jeff Noble (Wiley).

This chapter does describe how you can programmatically interact with CSS, modify it as needed, or even create new styles dynamically. You also discover how to produce some special effects by using CSS. Many developers work with external files when interacting with CSS. You can do that with JavaScript, but in the interest of making the examples clear, this chapter will work with CSS as part of HTML tags or within the header of the current page.

Changing HTML Elements

The focus of CSS is on the HTML element. CSS answers the question of how a <p> tag appears to the viewer. The following sections discuss two methods of working with HTML elements statically: as part of the individual tag and within a header that defines a style for all tags of the same type.

warning_bomb.eps It’s a mistake to assume that all browsers render CSS precisely the same. Two browsers on the same system running the same operating system often offer slightly different presentations. In addition, it’s an error to think that a browser will provide a consistent appearance on all platforms it supports. For example, Firefox presents slightly different displays when using Mac OS X, Linux, and Windows. A browser can also show the page differently when device constraints demand. A page shown on a smartphone screen differs from the same page shown on a PC. Think of CSS as more of a guideline than an absolute requirement.

Working with HTML tags

One of the options for configuring the HTML tags on a page is to grab all the tags of a certain type and format them as part of a loop. That's what the following example does. (You can find complete code for this example in the Chapter 13HTMLElements folder of the downloadable code as Tags.HTML.)

function ChangeStyles()

{

   // Modify the <h1> tag style.

   var Header = document.getElementsByTagName("h1")

   for (var i = 0; i < Header.length; i++)

   {

      Header[i].style.fontFamily = "Arial";

      Header[i].style.fontSize = "45px";

      Header[i].style.fontWeight = "bold";

      Header[i].style.color = "green";

      Header[i].style.textAlign = "center";

nbps;

      Header[i].style.marginLeft = "20px";

      Header[i].style.marginRight = "20px";

      Header[i].style.border = "medium double green";

   }

nbps;

   // Modify the <p> tag style.

   var Para = document.getElementsByTagName("p");

   for (var i= 0; i < Para.length; i++)

   {

      Para[i].style.fontFamily = "serif";

      Para[i].style.fontStyle = "italic";

      Para[i].style.fontSize = "1em";

      Para[i].style.color = "blue";

   }

}

In this case, the example uses getElementsByTagName() to obtain an array of all of the elements of a particular type on a page. The example formats both the <h1> and <p> tags on the page. When you have a list of these elements, you can format each element in turn by using a for loop as shown. (Chapter 9 discusses loops in detail.) The example shows a number of common formatting tasks, including setting the margins for an element.

ontheweb_modern.eps When you're working with graphic additions, such as a border, it helps to have an understanding of where the various styles fit into the picture. For example, the margin affects the distance between the edge of the screen and the border, and padding affects the distance between the border and the content it encloses. You can find a good discussion of this topic at http://www.w3.org/TR/CSS2/box.html.

You should notice a few features in this example. A fontFamily property can contain a family name, such as Arial, or a generic name, such as serif. The font size can appear in pixels (px) or ems (one em is equal to 16 px), amongst other value types. You can also use relative measures for the font size, such as small. Figure 13-1 shows typical output from this example.

9781118494189-fg1301.tif

Figure 13-1: Formatting elements as a group means you don’t need to know specific element identifiers.

Working with heading styles

Most developers are used to working with a <style> tag that appears in the <head> element of a page. JavaScript is able to construct a <style> tag for you programmatically as shown in the following example. (You can find complete code for this example in the Chapter 13HTMLElements folder of the downloadable code as HeadingTag.HTML.)

function ChangeStyles()

{

   // Obtain access to the header.

   Head = document.getElementsByTagName("head")[0];

   

   // Create a <style> tag.

   StyleTag = document.createElement("style");

   

   // Set the <style> tag type.

   StyleTag.type = "text/css";

   

   // Create a variable to hold the style information.

   var Styles =

      "h1 {font-family:Arial;font-size:45px;" +

      "font-weight:bold;color:green;text-align:center;" +

      "margin-left:20px;margin-right:20px;" +

      "border:medium double green;}" +

      "p {font-family:serif;font-style:italic;" +

      "font-size:1em;color:blue}";

   

   // Add the style to the <style> tag.

   StyleTag.appendChild(document.createTextNode(Styles));

   

   // Add the <style> tag to the heading.

   Head.appendChild(StyleTag);

}

The results from this example are precisely the same as the example in the preceding section. The difference is that the formatting information appears in the <style> tag rather than with each element individually. To make this example work, you construct the <style> tag content as a string. The application then uses the createTextNode() function to turn the string into a text node and inserts it as content for the <style> tag, StyleTag, using appendChild(). To add the <style> tag to the <head> element, the code calls the appendChild() function a second time.

Working with IDs

The techniques shown in the two preceding sections of the chapter work well when you want to modify the appearance of a group of tags. To change the appearance of specific tags, you must work with specific IDs as shown in the following example. (You can find complete code for this example in the Chapter 13HTMLElements folder of the downloadable code as ElementID.HTML.)

function ChangeStyles()

{

   // Modify the <h1> tag style.

   var Header = document.getElementById("Header");

   Header.style.fontFamily = "Arial";

   Header.style.fontSize = "45px";

   Header.style.fontWeight = "bold";

   Header.style.color = "green";

   Header.style.textAlign = "center";

   Header.style.marginLeft = "20px";

   Header.style.marginRight = "20px";

   Header.style.border = "medium double green";

   

   // Modify the <p> tag style.

   var Para = document.getElementById("Paragraph");

   Para.style.fontFamily = "serif";

   Para.style.fontStyle = "italic";

   Para.style.fontSize = "1em";

   Para.style.color = "blue";

}

In this case, only the elements with the specific identifiers provided by the code to the getElementById() function are modified in appearance. For example, when the code calls document.getElementById("Header"), Header receives a reference to the object with an id of Header, and the changes that follow only affect that particular object. The output is similar to the other two examples except the second paragraph remains unchanged.

Building Dynamic HTML Elements

One of the building blocks for creating special effects for any page is the ability to make dynamic changes to the page. For example, you may want to create a special effect for the selected element as shown in the following example. (You can find complete code for this example in the Chapter 13Dynamic folder of the downloadable code as Dynamic.HTML.)

function ChangeStyles(event)

{

   // Obtain a reference to the element.

   var ThisElement = document.getElementById(

      event.currentTarget.id);

   

   // Check the event type.

   if (event.type == "mouseover")

   {

      // Change the target element's CSS class.

      ThisElement.setAttribute("class", "Selected");

   }

   else

   {

      ThisElement.setAttribute("class", "Normal");

   }

}

This code accepts an event as input. The code obtains a reference to the element provided by the Event object. It then checks the event.type property to determine what type of event has happened (either a mouseover or a mouseout). The type of event determines what sort of formatting the element uses.

Of course, it would be handy to provide some sort of automation for assigning an event handler for the onmouseover and onmouseout events. The following code performs this task for you:

<script language="JavaScript">

   // Obtain a list of elements that use the <p> tag.

   var ElementList = document.getElementsByTagName("p");

   

   // Process each of these tags in turn.

   for(var i = 0; i < ElementList.length; i++)

   {

      // Add handlers for the mouseover and mouseout

      // events.

      ElementList[i].onmouseover = ChangeStyles;

      ElementList[i].onmouseout = ChangeStyles;

   }

</script>

This is another variant of interacting with a group of elements that use the same tag — the <p> tag in this case. The code obtains an array of these elements by calling getElementsByTagName(). It then assigns the ChangeStyles() function to the onmouseover and onmouseout properties of each element. The result is that each <p> tag on the page reacts when you hover the mouse over it.

Animating and Positioning HTML Elements

It's interesting to see what sorts of things you can do with a combination of CSS and JavaScript. For example, you could create an application that makes it possible for the user to drag and drop items around on the display. The following example is a little simpler than that. In this case, the code moves a button in response to a click. (You can find complete code for this example in the Chapter 13Dynamic folder of the downloadable code as Programmatic.HTML.)

function ChangeStyles()

{

   // Obtain a reference to the button.

   var ThisButton = document.getElementById("btnChange");

   

   // Change its absolute position onscreen.

   ThisButton.style.position = "absolute";

   ThisButton.style.left = "150px";

   ThisButton.style.top = "250px";

}

The code works by obtaining a reference to the button element, btnChange. It then sets the positioning for that element to absolute and makes changes to both the left and top properties. The result is that the control moves onscreen.

Creating JavaScript-Based Menus

All of the previous examples in this chapter prepare you in some way for this final example — a simple menu system that relies on a combination of CSS and JavaScript. The concept is straightforward. When you hover a mouse pointer over a menu, it opens any submenu and lets you choose one of the options on the submenu, if desired. Moving the mouse to a different menu closes the first submenu and opens another (assuming there’s one to open). The following sections take a three-phase approach to creating the menu:

check.png Define the HTML used to display the menu elements.

check.png Create the CSS required to make stylistic changes to the elements.

check.png Design code to make the menus open and close as needed.

The URLs used for this example aren't meant to be functional. If they actually end up taking you anywhere, it's purely coincidental. (You can find complete code for this example in the Chapter 13Menus folder of the downloadable code as JavaScriptMenu.HTML.)

Designing the HTML

This example is based on heavily formatted lists. There are many other ways to create menus, but this approach works quite well. Theoretically, you could easily store the menus on disk or in a database and use JavaScript to construct the required list code for you. However, for now, concentrate on the fact that this menu system is static and provides specific options as shown in the following code:

<ul id="menu">

   <li id="Item1">

      <a href="http://www.somewhere.com"

         onmouseover="CloseMenu()">Home</a>

   </li>

   <li id="Item2">

      <a href="http://www.somewhere.com"

         onmouseover="OpenMenu('Item2Submenu')">Events</a>

      <ul id="Item2Submenu"

          onmouseover="KeepSubmenu()"

          onmouseout="CloseMenu()">

         <a href="http://www.somewhere.com">Event 1</a>

         <a href="http://www.somewhere.com">Event 2</a>

         <a href="http://www.somewhere.com">Event 3</a>

      </ul>

   </li>

   <li id="Item3">

      <a href="http://www.somewhere.com"

         onmouseover="OpenMenu('Item3Submenu')">

            Contact Us

      </a>

      <ul id="Item3Submenu"

          onmouseover="KeepSubmenu()"

          onmouseout="CloseMenu()">

         <a href="http://www.somewhere.com">Telephone</a>

         <a href="http://www.somewhere.com">Mail</a>

         <a href="http://www.somewhere.com">E-mail</a>

      </ul>

   </li>

</ul>

There are three main menu options: Home, Events, and Contact Us. The Home menu lacks submenus. The Events menu does have a submenu consisting of Event 1, Event 2, and Event 3. The Contact menu provides Telephone, Mail, and E-mail as submenus. Figure 13-2 shows how the formatted menu will eventually appear.

9781118494189-fg1302.tif

Figure 13-2: The example provides a functional menu you can use on any site.

Defining the styles

The lists that you created in the preceding section won’t look much like a menu at the outset. The secret is the formatting provided by the CSS that follows:

<style type="text/css">

   #menu

   {

      margin: 0;

      padding: 0;

   }

   #menu li

   {

      margin: 0;

      padding: 0;

      list-style: none;

      float: left;

   }

   #menu li a

   {

      display: block;

      margin: 0 1px 0 0;

      padding: 4px 10px;

      width: 80px;

      background: black;

      color: white;

      text-align: center;

   }

   #menu li a:hover

   {

      background: green;

   }

   #menu ul

nbps;

   {

      position: absolute;

      visibility: hidden;

      margin: 0;

      padding: 0;

      background: grey;

      border: 1px solid white;

   }

   #menu ul a

   {

      position: relative;

      display: block;

      margin: 0;

      padding: 5px 10px;

      width: 80px;

      text-align: left;

      background: lightgrey;

      color: black;

   }

   #menu ul a:hover

   {

      background: #7f7fff;

   }

</style>

This CSS code is presented in the order of detail. The #menu formatting is for the topmost <ul id="menu"> tag. The main menu items are formatting in turn by the #menu li and #menu li a styles. When a user hovers the mouse over a main menu item, the #menu li a:hover style changes the background color to green. The submenu formatting is accomplished by the #menu ul and #menu ul a styles. Again, when the user hovers the mouse over a submenu item, the #menu ul a:hover style defines a color change for that menu item.

remember.eps The reason the example uses this approach for producing the special effects for this menu system is to demonstrate that it’s possible. You always have options when creating special effects. When you find that one approach isn’t working well, try another approach and you may find it works better.

Creating the JavaScript functions

The JavaScript functions have to perform four tasks. The first task is to track the status of the menu system and ensure that the menu remains stable. The following code performs that task:

// Holds the current open menu item.

var Item;

nbps;

// Holds the timeout value.

var Timer;

nbps;

// Hide the menu after clicking outside it.

document.onclick = CloseMenu;

The Item variable contains the current menu item. Timer holds a value that determines when a submenu will close automatically. If you don't provide this value, the menu behaves quite erratically, and users may find it difficult to select items. Finally, the code must provide a means to automatically close menu items when a user clicks outside the menu system, which is what the document.onclick = CloseMenu assignment does.

The second task is to provide a means for opening the submenus, which are hidden at the outset. Making the submenu visible allows access to the entries it provides. The following code shows a technique for opening the submenus:

function OpenMenu(Menu)

{

   // If there is an item that is open, close it.

   if (Item)

   {

      Item.style.visibility = "hidden";

   }

   

   // Obtain an item reference for the new menu.

   Item = document.getElementById(Menu);

   

   // Make it visible.

   Item.style.visibility = "visible";

}

Notice that the code first checks to ensure that the previous submenu is actually closed. Otherwise, the user could see two open submenus, which would definitely be confusing. After the code makes the previous submenu hidden, it makes the current submenu visible. In both cases, the example relies on the visibility property to perform the task.

The third task is to provide a method for closing a menu. This particular feature is a little tricky because you don’t necessarily want the menu to close immediately. Otherwise, the user won’t have time to select a submenu item before it closes. The following code shows how to perform this task with a time delay in place:

function CloseMenu()

{

   // Set a timer for closing the menu.

   Timer = window.setTimeout(PerformClose, 500);

}

nbps;

function PerformClose()

{

   // If the item is still open.

   if (Item)

   {

      // Close it.

      Item.style.visibility = "hidden";

   }

}

When the application requests that a submenu close, the code creates a 500 millisecond delay, after which the window automatically calls PerformClose(). When an item exists, PerformClose() sets its visibility property to hidden to hide the submenu from view.

There are three ways in which a submenu can close. A submenu can close when a user selects another main menu item, when the user moves the mouse cursor off of the submenu, or when the user clicks on a main or submenu item. When a user is hovering the mouse over a submenu item, the code must keep the submenu open. That’s the fourth task the application must perform using the following code:

function KeepSubmenu()

{

   // Reset the timer.

   window.clearTimeout(Timer);

}

As long as the user hovers the mouse over the submenu, it will remain open because the timer is constantly reset. The moment the user moves the mouse off the submenu or clicks one of the submenu items, the timer restarts, and the submenu closes.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.117.186.92