0

I'm still learning a bit on javascript/jquery and running into a bump. Every post I pull seems to over-complicate the process, unless it really does require all the extra code.

Here's what I'm doing:

  • Creating a vertical navigation menu with sliding menu's and static sub-menu's
  • Using HTML (5) layout with DL, DT and DD
  • Nav menu is using minor CSS for styling
  • Nav menu is using jQuery (1.8.3)

I have everything working the way I want, but because I'm picky, I want to temporarily disable the link after a menu is expanded. If I try to click the menu that is already expanded, it slides up and then back down. What I wanted to do is make it so it just doesn't react to a click if it's already expanded.

HTML of Nav Menu:

<dl class="nav2">
  <dt><a href="#">Thing1</a></dt>
    <dd>
        <ul>
            <li><a href="#">Test Def1</a></li>
            <li><a href="#">Test Def2</a><li>
            <li><a href="#">Test Def3</a></li>
        </ul>
    </dd>
  <dt><a href="#">Thing2</a></dt>
    <dd>
        <ul>
            <li><a href="#">Test Def4</a></li>
            <li><a href="#">Test Def5</a><li>
            <li><a href="#">Test Def6</a></li>
        </ul>
    </dd>
  <dt><a href="#">Thing3</a></dt>
    <dd>
        <ul>
            <li><a href="#">Test Def7</a></li>
            <li><a href="#">Test Def8</a><li>
            <li><a href="#">Test Def9</a></li>
        </ul>
    </dd>
</dl>

jQuery for Nav Menu:

$(document).ready(function() {
  $("dd:not(:first)").hide();
  $("dt a").click(function() {
    /* was thinking the added code would go here, but I could be wrong */
    $("dd:visible").slideUp("fast");
    $(this).parent().next().slideDown("fast");
    return false;
  });
});

I've tried a few things with bind and one, but due to my confusion with writing js/jquery, I'm not finding my trick. Is there anyway possible to say something like:

$(this:active).unbind("click");

or

if ($(this).active(function() {
  $(this).unbind("click");
} else {
  $(this).bind("click");
)};

I know I'm probably way off, but I'm trying. Is there any way to change this into javascript/jQuery?

When the DT A is clicked -
  make THIS DT / DT A not clickable;
  When THIS DT / DT A is no longer expanded or visible -
  make THIS DT / DT A clickable;

Thanks for the peak. Sorry if this was found somewhere. Each post I've ran into starts expanding this tiny change into several lines of code, whether attacking the CSS, longer then what seems to be needed javascript/jQuery or both. I just really want to try to keep it contained and simple (if at all possible).

SiLeNCeD
  • 240
  • 4
  • 13

2 Answers2

2

You do not want to disable the click (by disabling the anchor, or unbinding the event). You want to not execute an action when the clicked element is currently selected. Do that like this:

$(document).ready(function() {
    var active = $("dd:first");
    $("dd").not(active).hide();
    $("dt a").click(function() {
        var dd = $(this).parent().next();
        if (! dd.is(active)) {
            active.slideUp("fast");
            active = dd.slideDown("fast");
        }
        return false;
    });
});
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • Thanks... this is close to the same code I'm using and it works as intended. I'm going to just check a couple of different browsers to be thorough, but I really appreciate it! – SiLeNCeD Jan 16 '13 at 21:03
1

You could add a temporary class to a link which has been clicked, and then remove it once whatever action the event triggered is complete. Test for the class each time a link is click with hasClass, if it does, do nothing, if it doesn't, do something. I have answered a similar question here:

Suppress jQuery event handling temporarily

Here's how it would work with your code (I believe, though may need modification to suit your needs):

$(document).ready(function() {
  $("dd:not(:first)").hide();
  $("dt a").click(function(e) {

    // Prevent link from doing default action
    e.preventDefault();

    if ($(this).hasClass('fired') == false) {

        // Add 'fired' class to disable link
        $(this).addClass('fired');

        // Do some stuff
        $("dd:visible").slideUp("fast");
        $(this).parent().next().slideDown("fast");

        // Remove 'fired' class to re-enable the link
        // You may need to do this in a call back function
        // If you are animating something
        $(this).removeClass('fired');

    }

    // Use preventDefault instead of this
    /*return false;*/
  });
});
Community
  • 1
  • 1
Eric
  • 907
  • 7
  • 13
  • 1
    This was one of the things I wanted to steer away from. Adding code just to add/remove classes doesn't seem like it should be necessary if you can target the 'state' of an element. Thanks anyways though. – SiLeNCeD Jan 16 '13 at 21:07
  • Just curious: What benefits do you see using 'preventDefault' over 'return false'. From what I briefly looked into, 'return false' (atleast with jQuery) is similar to initiating both 'preventDefault' and 'stopPropogation', although 'preventDefault' seems useful in certain situations where you don't want to start an elements default response (I might have that wrong but there was a lot of back and forth on the posting). – SiLeNCeD Jan 16 '13 at 21:53