我正在创建一个样式化的选择菜单,其中我正在设置一个替换我的select元素的无序列表。
<div class="select">
<select name="distance" id="distance" class="select-hidden">
<option value="5.0 5"><font><font>5 mi</font></font></option>
<option value="6.0 4">6 km</option>
<option value="10.0 4" selected="selected"><font><font>10 km</font></font></option></select><div class="select-styled">10 km</div><ul class="select-options" style="display: none;"><li rel="5.0 5"><font><font>5 mi</font></font></li><li rel="6.0 4"><font><font>6 km</font></font></li><li rel="10.0 4"><font><font>10 km</font></font></li></ul>
</div>
然后我有这种风格
.select {
cursor: pointer;
display: inline-block;
position: relative;
font-size: 16px;
color: #000000;
width: 220px;
height: 42px;
}
现在我正在对宽度进行硬编码(220px),我的问题是我可以用一种不太严格的方式来构建它,这样宽度将自动成为最长元素名称的宽度吗?这是解释我的困境的小提琴 - https://jsfiddle.net/n73ao02h/13/。
答案 0 :(得分:0)
不要设置宽度,不要在select上设置display:none,在div.select-styled上设置white-space:nowrap
:
$(function() {
$('select').each(function(){
styleSelectMenu($(this));
});
});
// This method applies the styles to our select menu
function styleSelectMenu(selectMenu)
{
var $this = $(selectMenu), numberOfOptions = $(selectMenu).children('option').length;
$this.addClass('select-hidden');
if ( !$this.parent().hasClass('select') ) {
$this.wrap('<div class="select"></div>');
} // if
if ( !$this.next().hasClass('select-styled') ) {
$this.after('<div class="select-styled"></div>');
} // if
var $styledSelect = $this.next('div.select-styled');
$styledSelect.text($this.children('option').eq(0).text());
if ( $styledSelect.parent().find('ul').length > 0 ) {
$styledSelect.parent().find('ul').remove();
} // if
var $list = $('<ul />', {
'class': 'select-options'
}).insertAfter($styledSelect);
for (var i = 0; i < numberOfOptions; i++) {
$('<li />', {
text: $this.children('option').eq(i).text(),
rel: $this.children('option').eq(i).val()
}).appendTo($list);
}
var $listItems = $list.children('li');
// This is the event when someone opens the list
$styledSelect.unbind('click')
$styledSelect.click(function(e) {
e.stopPropagation();
$('div.select-styled.active').each(function(){
$(this).removeClass('active').next('ul.select-options').hide();
});
$(this).toggleClass('active').next('ul.select-options').toggle();
});
// This is the event when someone actually selects something from the list
$listItems.unbind('click.selectStyledItem')
$listItems.bind('click.selectStyledItem', function(event) {
clickListItem($styledSelect, $this, $(this), $list);
});
$(document).click(function() {
$styledSelect.removeClass('active');
$list.hide();
});
var selectedIndex = $this[0].selectedIndex;
if (selectedIndex > 0) {
var name = $this.attr("name")
var selectedText = $( "select[name='" + name + "'] option:selected" ).text();
selectItemFromStyledList($styledSelect, $this, selectedText, $list);
} // if
}
// This is the method that will select an item from the styled list
function selectItemFromStyledList(styledSelect, selectMenu, selectedText, listToHide)
{
$(styledSelect).text(selectedText).removeClass('active');
$(selectMenu).val($(selectMenu).attr('rel'));
$(listToHide).hide();
// Select option in the underlying list so that the form gets submitted
// with the right values
selectedOption = $(selectMenu).find("option").filter(function () { return $(this).html() == selectedText; });
$(selectMenu).find("option[selected='selected']").removeAttr("selected");
$(selectedOption).attr("selected","selected");
} // selectItemFromStyledList
// Called when someone clicks an item from the styled list
// The event data should contain the following parameters:
// styledSelect - the <div> element that contains the styled menu
// selectMenu - the actual form element that contains the items
// listItemClicked - the item that was clicked.
// list - THe <UL> element containig the <li> options
function clickListItem(styledSelect, selectMenu, listItemClicked, list)
{
var $styledSelect = $(styledSelect);
var $selectMenu = $(selectMenu);
var $listItem = $(listItemClicked);
var $list = $(list);
event.stopPropagation();
var selectedText = $listItem.text();
selectItemFromStyledList($styledSelect, $selectMenu, selectedText, $list)
} // clickListItem
&#13;
#statSearchFields {
vertical-align: top;
font-size: 90%;
}
.selectMenu {
font-family: 'Oxygen', sans-serif;
font-size: 20px;
height: 50px;
-webkit-appearance: menulist-button;
}
.select-hidden {
visibility: hidden;
padding-right: 10px;
}
.select {
cursor: pointer;
display: inline-block;
position: relative;
font-size: 16px;
color: black;
height: 42px;
}
.select-styled {
white-space: nowrap;
}
.select-styled {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
background-color: gray;
padding: 11px 12px;
@include transition(all 0.2s ease-in);
&:after {
content:"";
width: 0;
height: 0;
border: 7px solid transparent;
border-color: black transparent transparent transparent;
position: absolute;
top: 16px;
right: 10px;
}
&:hover {
background-color: darken(gray, 2);
}
&:active, &.active {
background-color: darken(gray, 5);
&:after {
top: 9px;
border-color: transparent transparent $select-color transparent;
}
}
}
.select-options {
display: none;
position: absolute;
top: 100%;
right: 0;
left: 0;
z-index: 999;
margin: 0;
padding: 0;
list-style: none;
background-color: darken(gray, 5);
overflow: scroll;
li {
margin: 0;
padding: 12px 0;
text-indent: 15px;
border-top: 1px solid darken(gray, 10);
@include transition(all 0.15s ease-in);
&:hover {
color: gray;
background: black;
}
&[rel="hide"] {
display: none;
}
}
}
#statSearchContainer {
padding: 10px;
font-family: "Calibre", "Helvetica Neue", "Helvetica", "Roboto", "Arial", sans-serif;
background-color: tan;
display: table;
}
#statSearchContainer h1 {
margin: 5px 0;
font-size: 1.0em;
}
#stat-search-form {
display: block;
padding: 0px;
}
#stat-search-form form input {
vertical-align: middle;
}
#statSearchFields {
vertical-align: top;
font-size: 90%;
}
.searchField {
display: inline-block;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="statSearchContainer">
<div class="searchField">
Distance<br/>
<select name="distance" id="distance"><option value="5.0 5">5 mi</option>
<option value="6.0 4">6 km</option>
<option selected="selected" value="10.0 4">10 km</option></select>
</div>
<input alt="Search" type="image" src="/assets/magnifying-glass-0220f37269f90a370c3bb60229240f2ef2a4e15b335cd42e64563ba65e4f22e4.png" class="search_button">
</div>
</div>
&#13;
答案 1 :(得分:0)
那是怎么回事:https://jsfiddle.net/n73ao02h/14/
没有任何width
的选择框将始终根据其选项进行设置。所以我们用它......
第一步是移除固定宽度
在我们添加display:none
之前,我们在JS中获得宽度
然后,我们生成一个零宽度的临时元素styled-select
,以自动获取CSS中定义的填充,而无需对其进行硬编码。
然后我们需要计算样式选择框的新宽度:
/* ... */
var $paddingCalculator = $('<div />', {
'class' : "select-styled test"
}).css({
width : 0,
visibility : "hidden"
}).appendTo("body");
var paddingWidth = $paddingCalculator.outerWidth();
$paddingCalculator.remove();
var selectWidth = $this.width() + paddingWidth;
$this.addClass('select-hidden');
if ( !$this.parent().hasClass('select') ) {
var $wrapper = $("<div />", {
'class' : "select"
}).css({
width : selectWidth
});
$this.wrap( $wrapper );
} // if
/* ... */
小附录:
请记住,原始选择框和样式div都需要具有相同的字体大小(以及任何与文本样式相关的内容,例如font-family,font-weight,letter-spacing,...)所以计算的尺寸是正确的。