javascript - 带有复选框 hack 的下拉列表 - 如何在不选择选项的情况下首次点击打开菜单?

标签 javascript html css checkbox

我想在表单中制作类似于下拉菜单的东西,但我希望能够在每个选项中显示图像或其他内容。有点像msdropdown但能够将任何内容放入下拉列表中,而不仅仅是图像。例如,我可能想要彩色矩形,它们是用 css 设置样式的内联 block 元素。

我目前接近它的方式是在这个 checkbox hack 的基础上构建

这是我目前所获得的,它在我测试过的桌面浏览器中运行良好: jsfiddle

问题在于,在 iOS 和 Android 上,当您单击下拉菜单将其展开时,它会选择列表中的第一个选项。我想要第一次单击以展开下拉列表,但还没有单击任何选项。有没有办法做到这一点,例如通过添加一些简单的javascript?

或者,是否有更优雅的方法来解决将任意内容放入下拉列表而不是使用复选框 hack 的整个问题?

下面来自 JSfiddle 的完整代码:

HTML

<p>Show what's currently selected, using javascript:</p>

<input type="text" value="" id="trace"/>

<p>Dropdown with custom styling, using the checkbox hack, along the lines of <a href="https://stackoverflow.com/a/9599581/3093080">this</a>, using the variant suggested by "namehere" in the comments.</p>

<form class="my-image-dropdown">
    <label>
        <input type="radio" name="line-style" value="1"  />
        <div class="dropdown-label">
            <span class="color-swatch vmiddle">
                <span style="background-color:red;">&nbsp;</span><span style="background-color:green;">&nbsp;</span><span style="background-color:blue;">&nbsp;</span>    
            </span>
            <span class="collapsedonly vmiddle">&#9662;</span>
            <span class="checkedonly vmiddle">&#x2713;</span>
        </div>
    </label>
    <label>
        <input type="radio" name="line-style" value="2" checked="checked"/>
        <div class="dropdown-label">
            <span class="color-swatch vmiddle">
                <span style="background-color:purple;">&nbsp;</span><span style="background-color:green;">&nbsp;</span><span style="background-color:pink;">&nbsp;</span>    
            </span>
            <span class="collapsedonly vmiddle">&#9662;</span>
            <span class="checkedonly vmiddle">&#x2713;</span>
        </div>
    </label>
    <label>
        <input type="radio" name="line-style" value="3" />
        <div class="dropdown-label">
            <span class="color-swatch vmiddle">
                <span style="background-color:grey;">&nbsp;</span><span style="background-color:darkblue;">&nbsp;</span><span style="background-color:black;">&nbsp;</span>    
            </span>
            <span class="collapsedonly vmiddle">&#9662;</span>
            <span class="checkedonly vmiddle">&#x2713;</span>
        </div>
    </label>
    <label>
        <input type="radio" name="line-style" value="4" />
        <div class="dropdown-label">
            <span class="color-swatch vmiddle">
                <span style="background-color:yellow;">&nbsp;</span><span style="background-color:orange;">&nbsp;</span><span style="background-color:green;">&nbsp;</span>    
            </span>
            <span class="collapsedonly vmiddle">&#9662;</span>
            <span class="checkedonly vmiddle">&#x2713;</span>
        </div>
    </label>
</form>

JavaScript

/* Update the trace showing currently selected option */
$( document ).ready(function() {
    var i = setInterval(function(){$("#trace").val($("input:checked").val());},100);
});

/* Fix the sticky hover bug on iOS - see http://www.dynamicdrive.com/forums/    entry.php?335-iOS-Sticky-Hover-Fix-Unhovering-dropdown-CSS-menus */
(function(l){var i,s={touchend:function(){}};for(i in s)l.addEventListener(i,s)})(document);

CSS

/* Hide the radio buttons */
.my-image-dropdown input {
    /*height: 0; width: 0; opacity:0;*/ /* This was in original code, seems unnecessary */
    display:none; /* Using display:none seems easier than setting height, width, opacity */
}


/* Style the container for both minimized and maximised state*/
.my-image-dropdown {
    width: auto; 
    height: auto; 
    background: #DDDDDD;
    border: 1px solid #999999;
    display: table;
    -webkit-border-radius: 5px;
    -moz-border-radius: 5px;
    border-radius: 5px;
    padding: 5px;
}


/* Collapse the dropdown when no hover, by hiding the contents of the label elements */
.my-image-dropdown label input ~ * {
    display:none;  
}


/* Expand the dropdown on hover (mouse) or tap (touch-screen) */
.my-image-dropdown:hover {
    height: auto;  /* Use fixed height or else auto to fit all color swatches */
    overflow-y: scroll;  /* If fixed height, use native scrolling */
}
.my-image-dropdown:hover label input ~ * {
    /* Use display:inline-block for tiling           */                             
    /*   or display:block;       for full-width vertical stacking */
    /*   or display:table;       for vertical stacking and fit to width of contents */
    display: table;  /* Vertical stacking and fit to width of contents */
}

/* Add some space between rows when expanded */
/* This uses the :not() selector which has pretty solid browser support */
/* http://caniuse.com/#feat=css-sel3 */
.my-image-dropdown:hover label:not(:first-child) input ~ * {
    margin-top: 10px;
}

/* Display the checked option even when the dropdown is collapsed */
.my-image-dropdown label input:checked ~ * {
    display:table;
    /* Optional: apply styling to the chosen option */
}

/* Apply effect when hovering over a particular label */
.my-image-dropdown label:hover input ~ * {
    opacity:0.5;
}

/* Show the down arrow only when collapsed and only for the checked option */
.my-image-dropdown label .collapsedonly {
    display:none;
}
.my-image-dropdown label input:checked ~ .dropdown-label .collapsedonly {
    display:inline;
}
.my-image-dropdown:hover label input:checked ~ .dropdown-label .collapsedonly {
    display:none;
}


/* Show a tick next to the checked option but only when expanded */
.my-image-dropdown label .checkedonly {
    display:none;
}
.my-image-dropdown:hover label input:checked ~ .dropdown-label .checkedonly {
    display:inline;
}


/* Style the tick and the down arrow */
.dropdown-label .checkedonly, .dropdown-label .collapsedonly {
    font-size: 120%;
    margin-left: 15px;
    margin-right: 5px;
}


/* Style the colored squares */
.color-swatch{
    display: inline-block;
}
.color-swatch > span {
    display: inline-block;
    width:50px;
    height:50px; /* If you change this then also change line-height of dropdown-label */
    margin:2px;
}

/* Vertically center an element within its neighbour */
.vmiddle {
    display: inline-block;
    vertical-align: middle;
}

最佳答案

经过反射(reflection),使用 jquery 从头开始​​编写下拉菜单代码比尝试修复复选框黑客攻击更容易。我找到的最佳解决方案是: http://www.jankoatwarpspeed.com/reinventing-a-drop-down-with-css-and-jquery/

关于javascript - 带有复选框 hack 的下拉列表 - 如何在不选择选项的情况下首次点击打开菜单?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40686152/

相关文章:

html - CSS 导航栏不在位

javascript - 如何找到 chrome 客户区和尺寸(不包括多功能框下拉菜单)

css - 如何使用 CSS 去除 IE8 中事件超链接周围的虚线边框

javascript - Backbone Marionette : Router Not Routing Correctly

javascript - 如何使用jQuery的delay()作为sleep()?

html - 将图像数据设置为要在 HTML 伪元素中使用的自定义 ISO 字符

html - 输入字段无法使用浏览器正确调整大小

javascript - React.lazy 警告

javascript - 浏览器检测所需的实际图像大小

css - 如何将 CSS 添加到特定的 div 类 - WordPress