多个下拉菜单 - onclick未关闭

时间:2015-07-21 15:12:49

标签: javascript jquery html css

当前的实现允许使用选择框并将它们转换为列表项,以便对它们进行样式设置。

问题在于,一旦打开下拉列表,关闭的唯一方法是单击文档或其他下拉菜单。

有没有人对最佳解决方法有任何建议,因为背后的原因是要确保如果有人点击另一个下拉项目,那么当前应该关闭。但是如果你只点击当前项目,切换只能激活它,而不是停用它。

var jq = jQuery.noConflict();
(function (jq) {

    // Iterate over each select element
    jq('.selectBoxStyle').each(function () {

        // Cache the number of options
        var sthis = jq(this),
            numberOfOptions = jq(this).children('option').length;

        // Hides the select element

        if (jq('html').hasClass('touch')) {

            jq('.options').addClass('s-hidden');

            sthis.wrap('<div class="select"></div>');

            // Insert a styled div to sit over the top of the hidden select element
            sthis.wrap('<div class="styledSelect"></div>');


        } else {

            sthis.addClass('s-hidden');

            // Wrap the select element in a div
            sthis.wrap('<div class="select"></div>');

            // Insert a styled div to sit over the top of the hidden select element
            sthis.after('<div class="styledSelect"></div>');

            // Cache the styled div
            var styledSelect = sthis.next('div.styledSelect');

            // Show the first select option in the styled div
            styledSelect.text(sthis.children('option').eq(0).text());

            // Insert an unordered list after the styled div and also cache the list
            var slist = jq('<ul />', {
                'class': 'options'
            }).insertAfter(styledSelect);

            // Insert a list item into the unordered list for each select option
            for (var i = 0; i < numberOfOptions; i++) {
                jq('<li />', {
                    text: sthis.children('option').eq(i).text(),
                        "data-value": sthis.children('option').eq(i).val(),
                        "class": sthis.children('option').eq(i).attr('class'),
                        "data-sku": sthis.children('option').eq(i).data('sku'),
                        "data-stock": sthis.children('option').eq(i).data('stock')
                }).appendTo(slist);
            }

            // Cache the list items
            var slistItems = slist.children('li');

            // Show the unordered list when the styled div is clicked (also hides it if the div is clicked again)

            styledSelect.click(function (e) {
                e.stopPropagation();
                //jq(this).toggleClass('clickme').removeClass('active');

                jq('div.styledSelect.active').each(function () {
                    jq(this).removeClass('active').next('ul.options').hide();
                    console.log(this);
                });

                jq(this).toggleClass('active').next('ul.options').toggle();


            });

            // Hides the unordered list when a list item is clicked and updates the styled div to show the selected list item
            // Updates the select element to have the value of the equivalent option
            slistItems.click(function (e) {
                e.stopPropagation();
                styledSelect.text(jq(this).text()).removeClass('active');
                jq(this).addClass("selected").siblings().removeClass("selected");
                sthis.val(jq(this).attr('value'));
                slist.hide();
                /* alert($this.val()); Uncomment this for demonstration! */
            });

            // Hides the unordered list when clicking outside of it
            jq(document).click(function () {
                styledSelect.removeClass('active');
                slist.hide();
            });
        }



    });
}(jq));
body {
    background-color:white;
}
.selectSizeMain {
    width: 56.77966%;
    float: none;
    margin: 2.1875rem auto auto;
}
.s-hidden {
    visibility:hidden;
    padding-right:10px;
}
.select {
    cursor:pointer;
    display:inline-block;
    position:relative;
    color:black;
    font-family: GibsonRegular, HelveticaNeue, Helvetica, sans-serif;
    font-size: 14px;
    font-size: .875rem;
    height: 40px;
    width: 100%;
}
.styledSelect {
    position:absolute;
    top:0;
    right:0;
    bottom:0;
    left:0;
    padding: 11px 13px;
    border: 1px solid #ddd;
    background-color: #fff;
}
.styledSelect:after {
    content:"";
    width:0;
    height:0;
    border:5px solid transparent;
    border-color:black transparent transparent transparent;
    position:absolute;
    top: 17px;
    right: 9px;
}
.styledSelect.active:after {
    content:"";
    width:0;
    height:0;
    border:5px solid transparent;
    border-color:green transparent transparent transparent;
    position:absolute;
    top: 17px;
    right: 9px;
}
.options {
    display:none;
    position:absolute;
    max-height: 280px;
    overflow-y:scroll;
    top:100%;
    right:0;
    left:0;
    z-index:999;
    margin:0 0;
    padding:0 0;
    list-style:none;
    border:1px solid #ccc;
    border-top:none;
    background-color:white;
}
.options li {
    padding: 11px 13px;
    margin:0 0;
}
.options li:hover {
    background-color: #000;
    color: #fff;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>

<div class="selectSizeMain">
    <select class="selectBoxStyle">
        <option value="">Choose Size</option>
        <option value="aye">Aye</option>
        <option value="eh">Eh</option>
        <option value="ooh">Ooh</option>
        <option value="whoop">Whoop</option>
    </select>
</div>
<select class="selectBoxStyle">
    <option value="">Month&hellip;</option>
    <option value="january">January</option>
    <option value="february">February</option>
    <option value="march">March</option>
    <option value="april">April</option>
    <option value="may">May</option>
    <option value="june">June</option>
    <option value="july">July</option>
    <option value="august">August</option>
    <option value="september">September</option>
    <option value="october">October</option>
    <option value="november">November</option>
    <option value="december">December</option>
</select>

1 个答案:

答案 0 :(得分:1)

您可以实现此目的的一种方法是检查点击的选择是否已经有.active类 - 然后,在关闭所有当前打开的选择后,您可以确定是否应该使用toggleClass("active")在它上面。

所以你的回调将从此转变:

styledSelect.click(function (e) {
    e.stopPropagation();

    jq('div.styledSelect.active').each(function () {
        jq(this).removeClass('active').next('ul.options').hide();
        console.log(this);
    });

    jq(this).toggleClass('active').next('ul.options').toggle();
});

到此:

styledSelect.click(function (e) {
    e.stopPropagation();
    var closeClicked = jq(this).hasClass("active");

    jq('div.styledSelect.active').each(function () {
        jq(this).removeClass('active').next('ul.options').hide();
        console.log(this);
    });

    if (!closeClicked){
        jq(this).toggleClass('active').next('ul.options').toggle();
    }    
});

这是一个JSFiddle来演示。它可能不是最优雅的解决方案,但它可以工作,只需要对您当前的代码进行微小的更改。希望这可以帮助!如果您有任何问题,请告诉我。