SitePoint Sponsor

User Tag List

Results 1 to 2 of 2

Hybrid View

  1. #1
    SitePoint Addict
    Join Date
    Jan 2009
    Posts
    370
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    jQuery - slideToggle Button select.

    Hi All

    I have a jsfiddle here - http://jsfiddle.net/eYV4n/

    Really simple navigation and a hidden div block beneath it.

    When you click the second link in the nav the div block slides down with slideToggle.

    When the div block slides down I would like the button clicked to be selected.

    I can do this when it's clicked by changing the background color.

    Is it possible to deselect the link (change it's color back) when the div block slides again.

    jquery.hover() handler hover-in and hover-out. Is it possible to do the same thing with slideToggle.

    Code:
    <!DOCTYPE html>
    <html>
      <meta charset="UTF-8">
      <meta name="description" content="">
      <meta name="keywords" content="">
      <meta name="robots" content="">
      <title>Title of the document</title>
    
      <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
    
      <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>  
    
      <style type="text/css">
        *{
          margin:0;
          padding:0;
        }
        body{
          background:#eee;
        }
        #wrap{
          background:#fff;
          max-width:800px;
          margin:0 auto;
          height:1000px;
        }
        ul{
          list-style:none;
          overflow:auto;
        }
        ul li{
          display:inline;
        }
        ul li a {
          float:left;
          display:block;
          color:#222;
          padding:10px;
          margin:0 5px 0 0;
        }
        #block{
          width:100%;
          margin:0 auto;
          height:200px;
          background:red;
          display:none;
        }
      </style>
    
      </head>
    
    <body>
      <div id="wrap">
        <nav>
          <ul>
            <li><a href="">One</a></li>
            <li><a href="" id="btn">Two &darr;</a></li>
            <li><a href="">Three</a></li>
            <li><a href="">Four</a></li>
          </ul>
        </nav>  
    
      <div id="block">
    
      </div>
    
      </div><!-- #wrap -->
    
    
      <script>
    
        $('#btn').click(function(e){
          e.preventDefault();
          $('#block').slideToggle('2000')
            $('#btn').css('background','red');
        })
    
    
      </script>
    </body>
    
    </html>

  2. #2
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,713
    Mentioned
    102 Post(s)
    Tagged
    4 Thread(s)
    Yes, you can do it by not changing the CSS class directly, and by using a class name instead. That allows you to then use toggleClass.

    [css]
    .selected {
    background: red;
    }
    [/css]

    Code javascript:
    $('#block').slideToggle('2000');
    $('#btn').classToggle('selected');

    But then you will notice that the button background gets toggles before the slide has completed. You can deal with that by checking if the block is visible or not, so that the button class can be toggled after the slide has finished, or beforehand.

    It's possible to delay something by supplying it as a callback to the slideToggle function, but we only want to do that half of the time, when the block is being slid up. So a function where we can provide the a function, a callback, and a boolean that decides whether to use it as a normal callback or to run the callback beforehand, would be a good idea. That function could be something like this:

    Code javascript:
    function useCallback(func, callback, precallCallback) {
        if (precallCallback) {
            callback();
            func();
        } else {
            func(callback);
        }
    }

    Although, the names useCallback and precallCallback might want to have more thought applied to their names.

    I've also placed the block and button references in to a variable, so that they can be consistantly accessed without a duplication of their names.
    It also means that if the "btn" id is moved to a different nav link, that things continue to work without any trouble.

    Code javascript:
    var button = this,
        block = '#block',
        slideBlock = function (callback) {
            $(block).slideToggle('2000', callback);
        },
        toggleButton = function () {
            $(button).toggleClass('selected');
        },
        blockHidden = !$(block).is(':visible');
     
    useCallback(slideBlock, toggleButton, blockHidden);

    You can see an example of this in action over at http://jsfiddle.net/pmw57/eYV4n/1/

    Can anyone think of a more appropriate way to name the parts of this function?

    Code javascript:
    function useCallback(func, callback, precallCallback) {
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •