tags:

views:

89

answers:

3

I try using evt.parent.attr("id") inside jsddm_close, but it doesn't work.

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"&gt;&lt;/script&gt;
<script type="text/javascript">
var ddmenuitem      = 0;

function jsddm_open()
{  
    // When "help-menu" being click, I will toggle drop down menu. 
    ddmenuitem = $(this).find('ul').eq(0).toggle();
}

function jsddm_close(evt)
{   
    // When everywhere in the document except "help-menu" being clicked, I will close the drop down menu.
    // How I can check everywhere in the document except "help-menu"?
    if (ddmenuitem) ddmenuitem.hide();
}

$(document).ready(function()
{   
    $('#jsddm > li').bind('click', jsddm_open);
    $(this).bind('click', jsddm_close);
});
</script>

<ul id="jsddm">
    <li><a href="#">Home</a></li>
    <li><a href="#" id="help-menu"><u>Help</u><small>xx</small></a>
        <ul>
            <li><a href="#">menu item 1</a></li>
            <li><a href="#">menu item 2</a></li>
        </ul>
    </li>  
</ul>
A: 

Let me preface this by saying I don't understand why you're implementing a menu. Just don't do it. There's no reason to. Get something like [superfish][1].

That being said, with your markup, this is how I would do it. The CSS:

#jsddm ul { display: none; } // hide by default

Now do you really want to click to toggle display? It's way more common to do it with hovering? In which case:

$(function() {
  $("#jsddm li").hover(function() {
    $(this).children("ul").show();
  }, function() {
    $(this).children("ul").hide();
  });
});

and you have a basic menu.

But to follow your path, it would be something like:

$(function() {
  $(document).click(function() {
    var jsddam = $(this).closest("#jsddm");
    if (jsddm.length == 0) {
      // did not click on the menu so hide the child items
      $("#jsddm ul").hide();
    } else {
      // otherwise find the relevant list item and show
      // the child <ul> elements
      $(this).closest("li").children("ul").toggle();
    }
  });
});

I believe that's closer to your intended behaviour (your question isn't 100% clear). The global variable with the reference is going to have all sorts of issues. If you need to remember something in this way it's generally better to use marker classes on DOM elements.

The way this works is it listens to all click() events basically. If they happened inside jsddm then the closest list item is found and it's <ul>s are toggled. If not, all the child <ul> of jsddm are hidden.

cletus
But but but... I get "undefined" when I alert the id...
Yan Cheng CHEOK
Not all elements have IDs.
Plynx
But I click on "Help". Isn't I should get "help-menu"?
Yan Cheng CHEOK
@Yan updated now you've posted some markup.
cletus
I think that is pretty much out of the topic, I just need a way to retrieve "help-menu" id element. Refer to my answer anyway. I already figure out how.
Yan Cheng CHEOK
Btw, just some extra note. I avoid using "hover" drop down menu, as I feel that is annoying. See how Google and Facebook implement. You need to explicitly click on the link with 1 down arrow, only the drop down menu will be shown. Amazon did it different way. Amazon is using hover.
Yan Cheng CHEOK
A: 
function jsddm_close(evt) {
    var id = evt.target.parentNode.id;
    if (id == 'help-menu') {
    }
    else {
        if (ddmenuitem) ddmenuitem.hide();
    }
}

or

function jsddm_close(evt) {
    var id = $(evt.target).parent().attr('id');        
    if (id == 'help-menu') {
    }
    else {
        if (ddmenuitem) ddmenuitem.hide();
    }
}
Yan Cheng CHEOK
A: 

That should works just like you except:

<script type="text/javascript">
function jsddm_open(e)
{ 
    $(this).find('ul').show();
    e.stopPropagation();
}

function jsddm_close(evt)
{   
    $("#jsddm ul").hide();
}

$(document).ready(function()
{   
    $('#jsddm > li').bind('click', jsddm_open);
    $(this).bind('click', jsddm_close);
});
</script>
Crozin