Chapter 13

Working with CSS and Graphics

In This Chapter

arrow Editing styles

arrow Employing images

arrow Executing JavaScript animations

arrow Developing a slideshow

To achieve style, begin by affecting none.

— E.B. White, The Elements of Style

Once you understand how to manipulate the DOM objects using JavaScript, web pages change from static documents into interactive applications that can respond to user input, change without reloading, and deliver live data to a variety of different computing devices.

Using the Style Object

The DOM’s Style object is a powerful tool for making a web page change its look and adapt in real time to user input or current browser conditions. The Style object gives programmers access to CSS style properties for any selected element or collection of elements in a document. (For more on the basic rules and syntax of CSS, see Chapter 1.)

Some of the things that you can do with the Style object are

  • Change text colors to highlight keywords entered into search boxes
  • Animate an object after a user clicks on it
  • Change the border and background color of the part of a form the user is currently editing
  • Expand and collapse or hide and show different parts of a page
  • Create tips or help boxes that appear above the content of the page when a user clicks a link

The Style object works the same way as other DOM objects. It includes a set of properties that you can use to get or set different aspects of a selected element.

The properties of the Style object mirror CSS properties. The difference between the two is that the DOM Style objects’ properties are spelled using camelCase instead of using CSS’s dashed format.

Table 13-1 shows a few of the most commonly used Style object properties, along with what CSS property they modify.

Table 13-1 Common Style Object Properties and Their CSS Equivalents

Property

CSS Style

Description

backgroundColor

background-color

Gets or sets the background color of an element

borderWidth

border-width

Sets the width of all four borders of an element

fontFamily

font-family

Gets or sets a list of font family names assigned to the text in an element

lineHeight

line-height

Gets or sets the distance between lines of text

textAlign

text-align

Gets or sets the horizontal alignment of text in a black element

tip For a complete list of the Style object’s properties, and of every other DOM objects properties, visit http://overapi.com/html-dom.

Getting the current style of an element

The Style object returns the currently applied inline styles of an element. It doesn’t tell you what the actual style is that the browser will render because it doesn’t include styles held in the external CSS files or styles inside of style elements.

For this reason, the Style object is not entirely useful for getting the style of an element. In Listing 13-1, the div element has an inline style and several style rules that are set within a style element.

When using the Style object to get the style properties of an element, only styles set using JavaScript or inline CSS are returned.

Listing 13-1: The Wrong Way to Get an Element’s Current Style

<html>
<head>
  <title>Getting Inline Styles</title>
  <style>
    #myText {
      color: white;
      background-color: black;
      font-family: Arial;
      margin-bottom: 20px;
      }
    #stylesOutput {
      font-size: 18px;
      font-family: monospace;
    }
  </style>
  <script>
    function getElementStyles(e){
      var colorOutput = "color: " + e.target.style.color;
      var fontSizeOutput = "font size: " + e.target.style.fontSize;
      document.getElementById("stylesOutput").innerHTML = colorOutput + "<br>" + fontSizeOutput;
    }

  </script>
</head>
<body>
  <div id="myText" style="font-size: 26px;" onclick="getElementStyles(event);">Here is some text.</div>
  <div id="stylesOutput"></div>
</body>
</html>

Figure 13-1 shows what happens when you load this page in a browser and click on the div element.

image

Figure 13-1: The result of using the Style object to get an element's style.

The two important things to notice about the results of this script are

  • The value of the Style object’s property is blank, even though the div’s color was set to white using CSS in the head.
  • The value of the Style object’s font size is set correctly because the CSS font-size property was set using inline CSS.

remember The style object’s properties behave like inline styles and will retrieve only the values of inline styles applied to an element.

A good way to get the current style of an element is by using window.getComputedStyle(), as shown in Listing 13-2.

Listing 13-2: The Correct Way to Get an Element's Current Style

<html>
<head>
  <title>Getting Computed Styles</title>
  <style>
    #myText {
      color: white;
      background-color: black;
      font-family: Arial;
      margin-bottom: 20px;
    }
    #stylesOutput {
      font-size: 18px;
      font-family: monospace;
    }
  </style>
  <script>
    function getElementStyles(e){
      var computedColor = window.getComputedStyle(e.target).getPropertyValue("color");
      var computedSize = window.getComputedStyle(e.target).getPropertyValue("font-size");

      var colorOutput = "color: " + computedColor;
      var fontSizeOutput = "font size: " + computedSize;
      document.getElementById("stylesOutput").innerHTML = colorOutput + "<br>" + fontSizeOutput;
    }

  </script>
</head>
<body>
  <div id="myText" style="font-size: 26px;" onclick="getElementStyles(event);">Here is some text.</div>
  <div id="stylesOutput"></div>
</body>
</html>

Figure 13-2 shows the output of Listing 13-2: showing the computed (and correct) style property values.

image

Figure 13-2: Displaying computed styles.

Notice in Listing 13-2, the getPropertyValue function takes the CSS property (font-size) rather than the style property (fontSize). The reason is that the script is querying the value of font-size directly from the element, rather than through the Style object (which will only tell us about the inline styles).

Setting style properties

To set properties of the Style object, select the element you want the new style to apply to and then use dot notation or bracket notation to assign a new value to a property of the Style object.

To change the border-width of an element that has the id of "borderedSquare", you would use the following code:

document.getElementById("borderedSquare").style.borderWidth = "15px";

Animating Elements with the Style Object

You can use CSS styles to control the look of elements, but you can also use them to control the positioning of elements. By using JavaScript loops with style property modifications, you can create basic animations fairly easily.

In Listing 13-3, a JavaScript function moves a square across the screen by using a for loop to change the CSS 'left' property.

Listing 13-3: Animating an Element with the Style Object

<html>
<head>
  <title>JavaScript animation</title>
  <style>
    #square {
      width: 100px;
      height: 100px;
      background-color: #333;
      position: absolute;
      left: 0px;
      top: 100px;
    }
  </style>
  <script>
    function moveSquare() {
      for (i=0; i<500; i++){
document.getElementById("square").style.left = i+"px";
      }
    }
  </script>
</head>
<body onload="moveSquare();">
  <div id="square"></div>
</body>
</html>

If you open this script in a browser, it seemingly opens with animation already complete. In fact, the animation actually does run, but it happens so fast that you can’t see it happening (unless you happen to have a very slow computer or very fast eyes).

What’s needed in order to make this animation run at human speed is a pause between each iteration of the loop. The most common way to create a loop with pauses is by using the setTimeout() method of the Window object.

The setTimeout() method takes two arguments:

  • A function or piece of code to run
  • A number of milliseconds (thousandths of a second) to wait before running

By putting a call to setTimeout() within a function and calling the function recursively, we can gain control over how fast the animation runs. (For more on writing recursive functions, see Chapter 7.)

In Listing 13-4, the box is now moving at the much slower pace of 1 pixel per 1/100th second. This example also features a few other improvements over Listing 13-3:

  • The square is now clickable. Clicking the square triggers the animation.
  • The animation of the square is based on the position of the square when the click event happens. Clicking on the square causes it to move 100 pixels to the right of wherever it is when it is clicked.

Listing 13-4: Animation with the Style Object, setTimeout(), and Recursion

<html>
<head>
  <title>JavaScript animation</title>
  <style>
    #square {
      width: 100px;
      height: 100px;
      background-color: #333;
      position: absolute;
      left: 0px;
      top: 100px;
    }
  </style>
  <script>
    // wait until the window is loaded
    window.addEventListener('load',initialize,false);

  function initialize(){

    //move the square when clicked
    document.getElementById("square").addEventListener('click',function(e){

      //get the starting position
      var left = window.getComputedStyle(e.target).getPropertyValue("left");

      //convert left to a base 10 number
      left = parseInt(left, 10);

      moveSquare(left,100);

    }, false);

  }

  function moveSquare(left,numMoves) {
    document.getElementById("square").style.left = left+"px";

    if (numMoves > 0) {
      numMoves--;
      left++;
      setTimeout(moveSquare,10,left,numMoves);
    } else {
      return;
    }
  }
  </script>
</head>
<body>
  <div id="square"></div>
</body>
</html>

Figure 13-3 shows the output of Listing 13-4 when run in a browser.

image

Figure 13-3: JavaScript enables animations based on events.

technicalstuff Look closely at the code that registers the click event on the square. An anonymous function is used as an event handler. Although it may look confusing at first glance, if you reduce it to its basic parts, it’s still just the same basic addEventListener() method at work, with its three arguments: the event type, the listener (in this case, an anonymous function), and the Boolean value for whether to use event capture.

Working with Images

HTML img elements are normally pretty static, unchanging things — unless the image is an animation, of course. With JavaScript, effects such as the resizing of images, repositioning images, lightbox effects, rollover effects, and more are all possible by manipulating the attributes of the img element and by changing CSS styles.

Using the Image object

The DOM’s Image object gives you access to the properties of an HTML img element. Once you have that access, you can set and get values in order to change any of the valid attributes of the element. The properties of the Image object are shown in Table 13-2.

Table 13-2 Properties of the Image Object

Property

Description

alt

Gets or sets the value of an image’s alt attribute

complete

Is true when the browser is finished loading the image

height

Gets or sets the value of an image’s height attribute

isMap

Gets or sets whether an image should be part of a server-side image-map

naturalHeight

Gets the image’s original height

naturalWidth

Gets the image’s original width

src

Gets or sets the value of an image’s src attribute

useMap

Gets or sets the value of an image’s usemap attribute

width

Gets or sets the value of an image’s width attribute

remember The most important and most widely used property of the Image object are the src property, the width property, and the height property. With these three properties, you can create image swap effects, amazing image size effects, cool rollover buttons, and a lot more!

Creating rollover buttons

A rollover button is a button that changes in some way when the mouse pointer is hovering over it. Rollover buttons are a great way to indicate to the user that an image can be clicked. You can also use them to reveal more information about what will happen if a button or a link is clicked. You can even use them just for fun or aesthetics. Some web designers like to put so-called easter eggs into their websites that will trigger image changes or other changes on a site when a mouse hovers over them or when someone clicks on certain hidden areas on a page.

tip You can create rollovers using CSS, but for more sophisticated rollovers or image swapping, JavaScript, or a combination of JavaScript and CSS, is required.

The example in Listing 13-5 shows how to create a simple image rollover effect in JavaScript.

Listing 13-5: An Image Rollover Effect

<html>
<head>
  <title>Rollover image</title>
  <script>

    function swapImage(imgToSwap){
      imgToSwap.src = "button2.png";
      imgToSwap.alt = "you're mousing over my button!";
    }
    function swapBack(imgToSwap){
      imgToSwap.src = "button1.png";
      imgToSwap.alt = "mouse over me!";
    }

  </script>
</head>
<body>
  <img src="button1.png" id="myButton" onmouseover="swapImage(this);" onmouseout="swapBack(this);" alt="mouse over me!">
</body>
</html>

technicalstuff In order for the page in Listing 13-5 to work correctly, you’ll need to have the images named button1.png and button2.png saved in the same directory as your HTML file. You can create your own or download ours from the books’ website.

Grow images on mouseover

Another useful user interface trick to make your websites more user-friendly is to slightly increase the size of image buttons when a user hovers over them. This nice little trick subtly indicates that the target image is clickable and provides a little bit of interactivity as well.

Listing 13-6 modifies the code from Listing 13-5 to increase the image size by 5 percent on mouseover events.

technicalstuff Be careful with increasing image sizes too far above the image’s natural size. If you increase it too much, the image quality will be noticeably degraded.

Listing 13-6: Increasing Image Size on mouseover

<html>
<head>
  <title>Rollover image size</title>
  <script>

    function growImage(imgToGrow){
      imgToGrow.width += imgToGrow.width * .05;
      imgToGrow.height += imgToGrow.width * .05;
    }
    function restoreImage(imgToShrink){
      imgToShrink.width = imgToShrink.naturalWidth;
      imgToShrink.height = imgToShrink.naturalHeight;
    }
  </script>
</head>
<body>
  <img src="button1.png" id="myButton" onmouseover="growImage(this);" onmouseout="restoreImage(this);" alt="mouse over me!">
</body>
</html>

technicalstuff You may have noticed that Listings 13-5 and 13-6 used the inline event method. While not ideal for actual web application development, inline events are frequently used for simple mouseover effects that are really interface-related rather than functionality-related.

Creating an image slideshow

Slideshows (also known as carousels) are a popular way to display multiple images in a single space on a site. Often used on the homepage of websites, they can really liven up your site.

Slideshows often feature transition effects to switch between multiple images. These transition effects are generally created using a library of JavaScript functions, such as jQuery. You can also create transition effects using just ordinary JavaScript, CSS, and the DOM. In the interest of simplicity, the slideshow in Listing 13-7 only switches between images and doesn’t feature a transition of any sort.

Listing 13-7: A Slideshow Built Using JavaScript and CSS

<html>
<head>
  <title>JavaScript slideshow</title>

  <style>
    #carousel {
      position: absolute;
      width: 800px;
      height: 400px;
      top: 100px;
      left: 100px;
      display: hidden;
    }

  </style>
  <script>
    var slides = [
      "<div id='slide1'>my first slide<br><img src='image1.jpg'></div>",
      "<div id='slide2'>my second slide<br><img src='image2.jpg'></div>",
      "<div id='slide3'>my third slide<br><img src='image3.jpg'></div>"];

    var currentSlide = 0;
    var numberOfSlides = slides.length-1;

    window.addEventListener("load",loader,false);
    
    function loader(){
      changeImage();
    }

    function changeImage(){
      console.log("changeImage function");
      if (currentSlide > numberOfSlides){
          currentSlide = 0;
      }
      
      document.getElementById("carousel").innerHTML=slides[currentSlide];

      console.log('displaying slide' + currentSlide + "of " + numberOfSlides);
      currentSlide++;

      setTimeout(changeImage,1000);
    }

  </script>
</head>
<body>
  <div id="carousel"></div>
</body>
</html>

Using the Style Object’s Animation Properties

CSS3 and the DOM’s Style object have properties for simplifying the task of animating elements. Used together, the animation properties can enable you to create some pretty cool animations with minimal effort. The Style object’s animation properties are listed in Table 13-3.

Table 13-3 Animation-Related Properties of the Style Object

Property

Description

animation

Sets all the animation properties except the animationPlayState property simultaneously.

animationDelay

Gets or sets a delay to happen before the animation starts

animationDirection

Gets or sets whether the animation should play in reverse on some or all cycles

animationDuaration

Gets or sets the length of time an animation takes to complete one cycle

animationFillMode

Gets or sets what values are applied by the animation outside the time it’s executing

animationIterationCount

Gets or sets the number of times an animation should be played

animationName

Gets or sets a list of animations, using keyframe at-rules

animationTimingFunction

Gets or sets the speed curve that describes how the animation should progress over time

animationPlayState

Gets or sets whether the animation is running or paused.

In Listing 13-8, a simple animation is created using CSS. The timing and keyframes of the animation are first configured with CSS, and then JavaScript is used to pause and resume the animation. With a little creativity, there are many possibilities for how you could control this animation using JavaScript.

tip CSS3 animation is still pretty new, and not all browsers support it in the same way. Because it’s still considered an experimental technology, some browsers require a browser prefix before the name of the animation properties.

In Listing 13-8, both the standard and prefixed CSS styles are included.

Listing 13-8: Controlling CSS3 Animation Using JavaScript

<!DOCTYPE>
<html>
<head>
  <style>
    #words {
      position: relative;
      width: 300px;
      height: 200px;
      text-align: center;
      padding-top: 20px;
      font-family: Arial;
      border-radius: 6px;
      color: white;

      /* Chrome, Safari, Opera */
      -webkit-animation-name: movewords;
      -webkit-animation-duration: 6s;
      -webkit-animation-timing-function: linear;
      -webkit-animation-delay: 0s;
      -webkit-animation-iteration-count: infinite;
      -webkit-animation-direction: alternate;
      -webkit-animation-play-state: running;
      /* Standard syntax */
      animation-name: movewords;
      animation-duration: 6s;
      animation-timing-function: linear;
      animation-delay: 0s;
      animation-iteration-count: infinite;
      animation-direction: alternate;
      animation-play-state: running;
    }

    /* Chrome, Safari, Opera */
    @-webkit-keyframes movewords {
      0% {background:red; left:100px; top:0px;}
      25%  {background:blue; left:200px; top:100px;}
      50%  {background:blue; left:300px; top:200px;}
      75%  {background:blue; left:200px; top:200px;}
      100% {background:red; left:100px; top:0px;}
    }

    /* Standard syntax */
    @keyframes movewords {
      0% {background:red; left:100px; top:0px;}
      25%  {background:blue; left:200px; top:100px;}
      50%  {background:blue; left:300px; top:200px;}
      75%  {background:blue; left:200px; top:200px;}
      100% {background:red; left:100px; top:0px;}
    }
  </style>
  <script>

    window.addEventListener("load",registerEvents,false);

    function registerEvents(e){
      document.getElementById("stop").addEventListener("click",stopAni,false);
      document.getElementById("go").addEventListener("click",startAni,false);
    }
    function stopAni(){
      document.getElementById("words").style.webkitAnimationPlayState = "paused";
      document.getElementById("words").style.AnimationPlayState = "paused";
    }
    function startAni(){
      document.getElementById("words").style.webkitAnimationPlayState = "running";
      document.getElementById("words").style.AnimationPlayState = "running";
    }

  </script>
</head>
<body>

  <h1 id="words">Movin' Around</h1>

  <button type="button" id="stop">Pause</button>
  <button type="button" id="go">Run</button>

</body>
</html>

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

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