jQuery for Designers Beginner's Guide Second Edition
上QQ阅读APP看书,第一时间看更新

Time for action – creating simple tabs

Perform the following steps to turn a list of links into tabs:

  1. We'll get started with our basic HTML file and associated folders, like we created in Chapter 1, Designer, Meet jQuery. Inside the <body> tag, we'll start by setting up a simple example that will work even for users with JavaScript disabled. We'll put a list of anchor links to different areas of the page at the top and then wrap each of our content sections in a div block with an ID, as shown in the following code:
    <header class="content">
      <h1>Noble Gases</h1>
      <p>Odorless, colorless, monatomic gases with very low chemical reactivity</p>
    </header>
    
    <ul id="tabs">
      <li><a href="#he">He</a></li>
      <li><a href="#ne">Ne</a></li>
      <li><a href="#ar">Ar</a></li>
      <li><a href="#kr">Kr</a></li>
      <li><a href="#xe">Xe</a></li>
      <li><a href="#rn">Rn</a></li>
    </ul>
    
    <div id="he">
      <h2>Helium</h2>
      <p>Info about helium here.</p>
    </div>
    
    <div id="ne">
      <h2>Neon</h2>
      <p>Info about neon here.</p>
    </div>
    
    <div id="ar">
      <h2>Argon</h2>
      <p>Info about argon here.</p>
    </div>
    
    <div id="kr">
      <h2>Krypton</h2>
      <p>Info about krypton here.</p>
    </div>
    
    <div id="xe">
      <h2>Xenon</h2>
      <p>Info about xenon here.</p>
    </div>
    
    <div id="rn">
      <h2>Radon</h2>
      <p>Info about radon here.</p>
    </div>

    Note that we added an id value of tabs to the list of links. This will make it easy to select the list with CSS for styling and with JavaScript to create the tab behavior.

    If you view this HTML in a browser, you'll see a list of links at the top of the page, which when clicked on the ID, jumps down to the appropriate section of the page so that the site visitor can easily find each section without scrolling on their own. We've basically created a clickable table of contents for our page.

  2. Next, we want to style our page a bit so that it looks nice for those site visitors who have JavaScript disabled. We only want these styles to apply to the page if JavaScript is disabled, so let's learn a handy technique. Add a class of jsOff to the <body> tag, as follows:
    <body class="jsOff">

    Now, you can reference this class in your CSS file to write styles for site visitors who have JavaScript disabled, using the following code:

    .jsOff ul#tabs {
      line-height: 1.5;
      margin: 1.125em 0;
    }

    Feel free to experiment with your CSS file and style the table of contents the way you want like for the no-JavaScript case.

  3. Now, we want to enhance this for our site visitors that have JavaScript enabled. We'll start by adding a class name to each of the <div> blocks that contain our sections of content—this will make it easier for us to select just the pieces of the page we want with jQuery and will also make it easier for us to further style our tabs with CSS. Have a look at the following code:
      <ul id="tabs">
        <li><a href="#he">He</a></li>
        <li><a href="#ne">Ne</a></li>
        <li><a href="#ar">Ar</a></li>
        <li><a href="#kr">Kr</a></li>
        <li><a href="#xe">Xe</a></li>
        <li><a href="#rn">Rn</a></li>
      </ul>
    
      <div id="he" class="content tab-section">
        <h2>Helium</h2>
        <p>Info about helium here.</p>
      </div>
    
      <div id="ne" class="content tab-section">
        <h2>Neon</h2>
        <p>Info about neon here.</p>
      </div>
    
      <div id="ar" class="content tab-section">
        <h2>Argon</h2>
        <p>Info about argon here.</p>
      </div>
    
      <div id="kr" class="content tab-section">
        <h2>Krypton</h2>
        <p>Info about krypton here.</p>
      </div>
    
      <div id="xe" class="content tab-section">
        <h2>Xenon</h2>
        <p>Info about xenon here.</p>
      </div>
    
      <div id="rn" class="content tab-section">
        <h2>Radon</h2>
        <p>Info about radon here.</p>
      </div>

    Here, we used the class of content to apply document-wide styles to the tabbed sections. We also added the tab-section class for styles specific to just the tabbed sections. The following screenshot shows what we've got so far:

  4. Now, we'll go back to the jsOff class we added to the <body> tag. Remember how we wrote some CSS styles that applied only when our site visitor has JavaScript disabled? Now, we can use some jQuery magic to change this class for site visitors who have JavaScript enabled.

    jQuery makes it easy for us to add or remove classes from elements. In this case, we want to remove the jsOff class from the <body> section. To do this, we'll use jQuery's removeClass() method. Then, we will add a new class called jsOn to the <body> section. To do this, we'll use jQuery's addClass method.

    Open the scripts.js file inside your scripts folder and write a document ready statement, as shown in the following code, just like we did in Chapter 1, Designer, Meet jQuery:

    $(document).ready(function(){
      // Our code will go here
    });

    Inside the document ready statement, write the following code to remove the jsOff class:

    $(document).ready(function(){
      $('body').removeClass('jsOff');
    });

    Next, we need to write the following code to add the new jsOn class:

    $(document).ready(function(){
      $('body').removeClass('jsOff');
      $('body').addClass('jsOn');
    });

    This code will work, but jQuery actually makes it a little bit easier for us. We can write less code! As we're working with the <body> element both times, we can actually write both of these methods on one line, as follows:

    $(document).ready(function(){
      $('body').removeClass('jsOff').addClass('jsOn');
    });

    Now we can use the jsOn class to write CSS just for those site visitors who have JavaScript enabled.

  5. We'll make use of the new jsOn class to hide all of our tab-section <div> elements. Inside the styles.css file, add the following CSS code to hide all the sections as soon as our page loads:
    .jsOn .tab-section {
      display: none;
    }

    Now, when we reload the page, we'll only see our table of contents as shown in the following screenshot:

  6. Now, let's write some CSS styles to get the list of links to look like tabs. Open the styles.css file that's inside your styles folder and add some CSS styles. As we want these styles to be applied only for site visitors with JavaScript enabled, we'll use the jsOn class in our selectors. Feel free to customize the CSS code to suit your own taste. I have customized it as follows:
    .jsOn ul#tabs {
      background: #a0d468;
      border-top-left-radius: 7px;
      border-top-right-radius: 7px;
      font-size: 1.5em;
      margin: 1.5em 0 0 0;
    }
    
    .jsOn ul#tabs:after {
      clear: both;
      content: '';
      display: table;
    }
    
    .jsOn ul#tabs li {
      display: block;
      float: left;
    }
    
    .jsOn ul#tabs a {
      border-right: 1px solid #8cc152;
      color: white;
      display: block;
      padding: 0.5em 1.125em;
      text-decoration: none;
    }
    
    .jsOn ul#tabs li:first-child a {
      border-top-left-radius: 7px;  
    }
    
    .jsOn ul#tabs a:hover {
      background: #8cc152;
    }
    
    .jsOn .tab-section {
      background: white;
      color: #444;
      padding: 2em;
    }
    
    .jsOn .tab-section h2 {
      margin-top: 0;
    }

    Note that this sample CSS uses several CSS3 properties that, at the time of publication, are not supported by all browsers. Feel free to add in vendor prefixes to get these styles working in more current browsers if you wish. Have a look at the following screenshot:

    Tip

    Browser support for new features

    If you're curious to know what browser support is available for different new CSS3 properties you might like to use in your CSS, a great resource to check out is http://caniuse.com. It's kept up to date and will give you detailed information about which browsers support each new property.

  7. Next, let's get our tabs working. When a site visitor clicks on a tab, we want to show the appropriate section of content. First, we have to select the element or elements that we want to work with. In this case, we want to do something when our site visitor clicks on a link inside the <ul> element with the id value of tabs. We can select these links as follows:
    $(document).ready(function(){
      $('body').removeClass('jsOff').addClass('jsOn');
    
      $('#tabs a')
    });
  8. Now, we've got the links and we want to do something when these links are clicked. jQuery makes this easy for us with the on() method, which looks like the following code snippet:
    $(document).ready(function(){
      $('body').removeClass('jsOff').addClass('jsOn');
    
      $('#tabs a').on();
    });

    In this case, we want to do something when our site visitor clicks on one of the tab links. In JavaScript, the click is called an event. There are all sorts of events: clicking on an element, moving the mouse over an element, changing the text in a form field, submitting a form, and so on. We just have to tell jQuery which event we're working with. In this case, it's click:

    $('#tabs a').on('click');

    Now, jQuery knows that we want to do something when the user clicks on a tab link, but we haven't said what we want to do. We can say what should happen with a function, as follows:

    $('#tabs a').on('click', function(){
      // Event code will go here
    });

    In JavaScript, this function is called an event handler. That makes sense, right? It's the code that handles an event.

  9. Remember how the page worked when JavaScript was disabled? The list of links appeared at the top of the page, and clicking on one of them would jump to the corresponding section of the page. As we're going to hide and show those bits of content depending on which link was clicked, we need to make sure that we cancel the default action—we don't want the page to jump. The following code is how we cancel the browser's default reaction to an event:
    $('#tabs a').on('click', function(e){
      e.preventDefault();
    });

    We have to pass our event inside the parentheses of the function shown in the preceding code. You may call this what you want. Sometimes, developers will name it e, event, or evt. Then, inside our function, we call the preventDefault method for the event. If you load the page in a browser at this point, you'll see that clicking on the links does nothing—the default action has been cancelled. Now, we have to write a function to specify what should happen instead.

  10. When a site visitor clicks on a table of contents link, we want to select the appropriate section and show it. To do this, we'll use hash, or the part of the href attribute that includes the # symbol:
    $('#tabs a').on ('click', function(e){
      $(this.hash).show();
      e.preventDefault();
    });

    When we pass this.hash to the jQuery function, the this keyword we're dealing with is the link that was just clicked on and this.hash is the value of the href attribute starting with the # symbol and continuing to the end. For example, if a site visitor were to click on the He tab, passing this.hash to the jQuery function is the same as writing the following line of code:

    $('#he');

    Of course, we've done it in a much more flexible way and our code will work for any tab linked to any section of the site. So, for example, if I wanted to remove the Rn tab or expand my list to include the halogens in addition to the noble gases, I wouldn't have to update JavaScript, only the HTML markup itself—JavaScript is flexible enough to adjust to changes.

  11. If you reload the page in the browser at this point, you'll see that when you click on one of the tab links, the associated section becomes visible. We're making progress! However, if you keep clicking on links, the sections just keep showing up, and after clicking on all the links, all the sections are visible—this not what we want. We'll have to hide the visible section and show only the section we want. Let's add a line to our code, as follows, to select the visible <div> with the class of tab-section and hide it before we show the new section:
    $('#tabs a').on('click', function(e){
      $('.tab-section:visible').hide();
      $(this.hash).show();
      e.preventDefault();
    });

    You're probably familiar with pseudoclass selectors in CSS—they're often used to select the hover, visited, and active states of links (a:hover, a:visited, and a:active). jQuery makes a few additional pseudoclass selectors available to us. There are pseudoclass selectors for buttons, empty elements, disabled form fields, checkboxes, and so on. You can check out all the available selectors for jQuery in the jQuery documentation at to select the .tab-section that's currently visible. Once we've selected the visible .tab-section, we hide it and then find the correct tab-section and show it.

  12. Now, if you load this in a browser, you'll see that there's something missing; we should highlight the currently selected tab to make it obvious which one is selected. We can do that by adding a CSS class to the current tab. Go back to your scripts.js file and add a bit of code to add a class to the current tab and remove the class from any non-current tabs as follows:
    $('#tabs a').on ('click', function(e){
      $('#tabs a.current').removeClass('current');
      $('.tab-section:visible').hide();
      $(this.hash).show();
      $(this).addClass('current');
      e.preventDefault();
    });

    First, we'll find the tab that has the current class and remove this class. Then, we'll get the tab that was just clicked and add the current class to it. In this way, we make sure that only one tab will be marked as the current tab at any given time.

    The $(this) element is the jQuery way of referring to the jQuery object that we're currently working with. In this case, we're selecting all the tab links and we've attached this function to be called whenever our site visitor clicks on a link. When a site visitor clicks on a link, we want to work with the link that was clicked. A simple and quick way of referring to the current link is to use $(this).

  13. Next, we'll add some styles in our CSS file for our new class. Open styles.css and add a bit of CSS to distinguish the currently selected tab. I'm styling mine as follows, but feel free to customize the style to suit your own tastes:
    .jsOn ul#tabs a.current {
      background: #4fc1e9;
    }
  14. Now our tabs are working the way we expect, and the only thing left to do is to make the first tab active and show the first content section when the page is first loaded instead of leaving them all hidden. We've already written the function to do this, so now all we have to do is call it for our first tab, as shown in the following code snippet:
    $('#tabs a').on ('click', function(e){
      $('#tabs a.current').removeClass('current');
      $('.tab-section:visible').hide();
      $(this.hash).show();
      $(this).addClass('current');
      e.preventDefault;
    }).filter(':first').click();
    

    The jQuery object's filter method will allow us to filter a previously selected set of elements. In this case, we're dealing with all of the <a> tags inside the <ul> tags with the #tabs ID. We bind a click function to all of these links, then we'll filter out just the first link using the :first pseudoclass made available to us in jQuery, and tell jQuery to click on the first tab for us. This will run our function, adding the current class to the first link and showing the first .tab-section—just the way we'd expect the page to look when we load it, as seen in the following screenshot:

What just happened?

We set up a set of simple tabs with jQuery. For site visitors with JavaScript disabled, the tabs will function like a table of contents at the top of the document, jumping them to the various sections of content when they're clicked. For site visitors with JavaScript enabled, the sections of content will be completely hidden until needed. Clicking on each tab reveals the content associated with that tab. This is a great way to save space in a UI, making all the content available on demand in a small space.

We used our jsOn class name to hide the tab contents to be sure that users without JavaScript enabled would still be able to access all of our content.

Pop quiz – working with events

Q1. Which of the following are the examples of events in JavaScript?

  1. Clicking on a link
  2. Entering a value in a form input
  3. Moving the mouse over an image
  4. Pressing a key on the keyboard
  5. All of the above

Q2. What is an event handler?

  1. The site visitor that decides which button to click
  2. A bit of code that is run in response to an event
  3. The site visitor submitting a form