简体   繁体   中英

How do I make a drop down menu close as another from the same class opens in jquery / javascript?

I've created a dropdown menu with links to click on that enable the user to delete a message, block commenting etc of a post.

Anyway it's all working as expected..however there is some behaviour I'd like to stop. If user clicks on the arrow to display the drop down menu it shows which is fine but when a user scrolls to another message/post and clicks the arrow again both drop down menus remain open.

  1. I'd like to have the current menu open close when another one opens. So only 1 menu can be open at a time.

  2. For some reason when I click on the arrow to drop down the menu for the first time after a page refresh the arrow hover state flickers once as I scroll of it. Is there anyway to stop this?

Here is my current code:

Jquery:

$(".micropostOptions").click(function(e) {

    var $micropostOptions = $(this),
        $postMenu = $micropostOptions.children();

    e.stopPropagation();

        if ($postMenu.hasClass("postMenuActivate")) {
            $postMenu.hide().removeClass("postMenuActivate");
            $micropostOptions.removeClass("postMenuHoverState");
        } else {
            $postMenu.show(10).addClass("postMenuActivate");
            $micropostOptions.addClass('postMenuHoverState');
        };

});

sCSS:

.micropostOptions {
    position:absolute;
    height:17px;
    width:17px  ;
    top:5px;
    right:5px;
    background:white url("/assets/arrow_down_alt1.png") no-repeat;
    background-position:0px 0px;

        &:hover {
            background: url("/assets/arrow_down_alt1_hover.png") no-repeat; 
            background-position:0px 0px;
            cursor:pointer !important;

        }

}

.postMenuActivate {
    display:block;
}

.postMenuHoverState {
    background: url("/assets/arrow_down_alt1_hover.png") no-repeat; 
    background-position:0px 0px;
    cursor:pointer !important;
}

.postMenu {
    position:absolute;
    display:none;
    padding-bottom:20px;
    background-color:white !important;
    border:1px solid $main-background-color;
    height:163px;
    width:170px;
    top:18px;
    right:2px;
    -webkit-box-shadow: 0 10px 6px -6px #777;
    -moz-box-shadow: 0 10px 6px -6px #777;
    box-shadow: 0 10px 6px -6px #777;
    color:gray;
    z-index:3000;

        li {

        font-size:12px;
        height:33px;
        background-color:white !important;

            a span {
                float:left;
                width:160px;
                height:33px;
                line-height:33px;
                padding-left:10px;
                color:gray;

                  &:hover {
                    background-color:#4D90FE !important;
                    color:white;
                    //  #DD4B39,#D14836
                    }
            }

            &:hover {
            background-color:#4D90FE;
            color:white;

            }
        }

        .deletePost {
            //position:relative;
            padding-top:0px !important;
            padding-left:0px !important;
            height:39px;
            width:170px;
            text-align:center;
            padding-bottom:7px;
            border-bottom:1px solid #d9d9d9;

                a {

                    span {
                    float:left;
                    padding-left:0px !important;                            
                        height:46px !important;
                        width:170px !important;
                        line-height:46px;
                    }
                }

                a span:hover {
                    background-color:#DD4B39 !important;
                    color:white;
                //  #DD4B39,#D14836
                }
        }

        .reportAbuse {
            border-top:1px solid #d9d9d9;

                a span:hover {
                    background-color:gray !important;;
                }

        }

}

HTML:

    <nav class="micropostOptions">
     <ul class="postMenu">
       <li class="deletePost"><%= link_to content_tag(:span, "Delete post"), m, :method => :delete, :confirm => "Are you sure?", :title => m.content, :class => "message_delete" %>
       </li>
       <li class="disableCommenting"><%= link_to content_tag(:span, "Pause commenting"), "2" %></li>
       <li class="blockCommenter"><%= link_to content_tag(:span, "Block commenter"), "3" %></li>
       <li class="openInNewWindow"><%= link_to content_tag(:span, "Open in new window"), "4" %></li>
       <li class="reportAbuse"><%= link_to content_tag(:span, "Report abuse"), "5" %></li>
     </ul>  
   </nav>

Kind regards

I could not replicate your codes in a demo, so I changed the CSS:

jsFiddle demo

$('.micropostOptions').on('click',function(){
    var postMenu = $(this).find('.postMenu');
    
    if( postMenu.is(':hidden') ){
        $('.postMenu').slideUp();
        postMenu.slideDown();
    }else{
        postMenu.slideUp() ;
    }
});

Shooting a little blind here, since we only have what looks like one menu, but does this solve the issue?

$(".micropostOptions").click(function(e) {

    var $micropostOptions = $(this),
        $postMenu = $micropostOptions.children();

    e.stopPropagation();

        if ($postMenu.hasClass("postMenuActivate")) {
            $postMenu.hide().removeClass("postMenuActivate");
            $micropostOptions.removeClass("postMenuHoverState");
        } else {
            $postMenu.show(10).addClass("postMenuActivate");
            $micropostOptions.addClass('postMenuHoverState');
            $(".micropostOptions.postMenuHoverState")  //selects all micropostOptions with the postMenuHoverState class
                .not($micropostOptions)  //removes the current micropostOptions from the selected set
                .removeClass('postMenuHoverState')  //removes the postMenuHoverState class from all micropostOptions (besides teh current one)
                .children()  //gets the child menus of the set
                    .removeClass('postMenuActivate');  //removes postMenuActivate class from children of the active (but not current) micropostOptions

        };

});

I think, you should have a look at jQuery's blur() event handler to fire an event when an element loses its focus: http://api.jquery.com/blur/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM