tags:

views:

763

answers:

5

i am trying to develop my own accordion/sliding menu. (as a side qn, any good ones that can be easily customized/skinned?)

i found that seem to trigger when i am sliding down an "inner" menu. since its "inner", my mouse definately has not left #mainnav

my test page here

without that annoying test alert here

$("#mainnav").mouseleave(function() {
    alert("mouseleave #mainnav");
});

more complete source:

$(function() {
    $("#mainnav > li > a").hover(mouseOver);
    $("#mainnav").mouseleave(function() {
        alert("mouseleave #mainnav");
    });
});
function mouseOver() {
    $(this).next("ul").slideDown("fast", function() {
        $("li:has(ul) > a", this).hover(mouseOver);
    });
}
#mainnav, #mainnav ul {
    list-style: none;
    padding: 0;
    margin: 0;
    background: #bbb;
}
#mainnav ul {
    display: none;
    margin: 5px 10px;
}
#mainnav a {
    display: block;
    padding: 5px 10px;
    margin: 2px 0;
    background: yellow;
}
<ul id="mainnav">
    <li><a href="#">Test</a></li>
    <li><a href="#">Test</a></li>
    <li><a href="#">Test</a></li>
    <li> 
        <a href="#">Test</a>
        <ul>
            <li><a href="#">Test</a></li>
            <li> 
                <a href="#">Test 1</a>
                <ul>
                    <li><a href="#">Test</a></li>
                    <li><a href="#">Test</a></li>
                    <li><a href="#">Test</a></li>
                </ul>
            </li>
            <li><a href="#">Test</a></li>
        </ul>
    </li>
    <li><a href="#">Test</a></li>
    <li><a href="#">Test</a></li>
</ul>
A: 

The jQuery UI accordion uses CSS generated by ThemeRoller. You can even further customize the CSS produced by ThemeRoller.

As to your problem, I suspect it's an issue with jQuery simulating the event (it's Microsoft proprietary). The example on the jQuery site uses DIVs and paragraphs and it seems to work as advertised. You might want to try stopping the propagation of the "hover" event to see if that prevents the mouseout on the child from triggering mouseleave on the parent.

EDIT: I just noticed that your hover method only has one callback. I believe it takes two, and you need to stop propagation in both. The following seems to do the trick but to make it work (since leaving the anchor on either end has the event block) I had to wrap the whole thing in a DIV with padding 5 and attach the mouseleave event to it.

$(function() {
    $("#mainnav > li > a").hover(
         mouseOver,
         mouseOut
    );
    $("#navContainer").mouseleave(function() {
        alert("mouseleave #mainnav");
    });
});

function mouseOver(e) {
    $(this).next("ul").slideDown("fast", function() {
        $("li:has(ul) > a", this).hover(mouseOver, mouseOut);
    });
    e.stopPropagation();
}
function mouseOut(e) {
    e.stopPropagation();
}

<div id="navContainer" style="padding: 5;">
   ... your list ...
</div>
tvanfosson
oh "You might want to try stopping the propagation of the "hover" event to see if that prevents the mouseout on the child from triggering mouseleave on the parent"... maybe i will look into that.
iceangel89
how do i do it tho?
iceangel89
i tried function mouseOver(e) { // some code e.stopPropagation();}same problem happens
iceangel89
What a silly hack. Read up on mouseleave vs mouseout in the link I posted above. There's no need for any of this.
Sneakyness
@Sneakyness -- I guess I'm just dense. How is it that going from the inner list to a list element of the outer list is leaving the outer list when all if it is contained within the outer list element?
tvanfosson
it seems moving into the link triggering the slidedown will cause the mouseleave of the parent
iceangel89
A: 

There isn't a single JQuery accordion/sliding menu/anything that isn't easily skinned and customized. They all use CSS.

Sneakyness
ok, anyone for the main qn?
iceangel89
A: 

You seem to have found a reliable way to crash Google Chrome with that script. Weird.

Maybe you need to also select all child elements.

$("#mainnav, #mainnav > *").mouseleave(function() {
    alert("mouseleave #mainnav");
});
thezachperson31
i think u misunderstand me. i want to trigger the event only after i left #mainnav the whole navigation, not any inner ul
iceangel89
and i crash google chrome? definitely didn't intend to ... really crashed? i tot it was a simple script
iceangel89
A: 

Maybe it has to do with event propagation? Maybe you need to stopPropagation?

meder
i am thinking something is weird with the selector, which seems correct tho, maybe because of margins cause this... stopPropagation where/when? why do u say its because of propagation tho?
iceangel89
+2  A: 

Use a Web Inspector. Safari has one, Firefox has firebug. Grab one of them, you'll notice that it happens whenever you're entering one of the list items. You ARE leaving mainnav. I don't think you understand the way Box Model and the JQuery events system works. Here's a good resource on Box Model (follow the link he mentions and read all of that too, it is necessary to understand this before you will be able to understand your problem). Here is the events/mouseleave page in JQuery's documentation. If you would have read this a long time ago, you would not be here asking this very question. They even put it in bold for you. Their documentation is excellent.

Mouseout fires when the pointer moves into or out from child element, while mouseleave doesn't.

I'm not going to write your code for you, you need to learn these things on your own. This is a crucial part of JQuery/CSS that cannot be skipped over if you intend to write your own scripts.

Sneakyness
hmm but i am using mouse leave? $("#mainnav").mouseleave(function(e) {...})
iceangel89
the box model part was because i tot moving into a child element shld still be inside the parent
iceangel89
i notice if i remove the showing and hiding effect, when i move into child elements nth happens but if i have the slide down effect, moving into the element triggering that effect, triggers mouseleave
iceangel89