#width_tmp
嵌套在 .input-group-btn
下,所以它继承了 bootstrap 的 font-size: 0;
属性。因此,该元素的计算宽度始终为零:
<span id="width_tmp"></span>
移出输入组即可。
// resize on initial load
document.querySelectorAll("select").forEach(resizeSelect)
// delegated listener on change
document.body.addEventListener("change", (e) => {
if (e.target.matches("select")) {
resizeSelect(e.target)
}
})
function resizeSelect(sel) {
let tempOption = document.createElement('option');
tempOption.textContent = sel.selectedOptions[0].textContent;
let tempSelect = document.createElement('select');
tempSelect.style.visibility = "hidden";
tempSelect.style.position = "fixed"
tempSelect.appendChild(tempOption);
sel.after(tempSelect);
sel.style.width = `${+tempSelect.clientWidth + 4}px`;
tempSelect.remove();
}
// resize on initial load
document.querySelectorAll("select").forEach(resizeSelect)
// delegated listener on change
document.body.addEventListener("change", (e) => {
if (e.target.matches("select")) {
resizeSelect(e.target)
}
})
function resizeSelect(sel) {
let tempOption = document.createElement('option');
tempOption.textContent = sel.selectedOptions[0].textContent;
let tempSelect = document.createElement('select');
tempSelect.style.visibility = "hidden";
tempSelect.style.position = "fixed"
tempSelect.appendChild(tempOption);
sel.after(tempSelect);
sel.style.width = `${+tempSelect.clientWidth + 4}px`;
tempSelect.remove();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select>
<option value="2">Some longer option</option>
<option value="1">Short option</option>
<option value="3">An very long option with a lot of text</option>
</select>
<select>
<option>Short option 2</option>
<option>Some longer option 2</option>
<option selected>An very long option with a lot of text 2</option>
</select>
另一种选择是使用插件来处理整个操作的开始和结束。这里是我刚刚编写的一个插件。
该插件动态创建和销毁,因此不会混杂在您的HTML中。这有助于分离关注点,并使您能够将该功能委托给另一个文件,并轻松地在多个页面上重复使用多个元素。
(function($, window){
$(function() {
let arrowWidth = 30;
$.fn.resizeselect = function(settings) {
return this.each(function() {
$(this).change(function(){
let $this = $(this);
// get font-weight, font-size, and font-family
let style = window.getComputedStyle(this)
let { fontWeight, fontSize, fontFamily } = style
// create test element
let text = $this.find("option:selected").text();
let $test = $("<span>").html(text).css({
"font-size": fontSize,
"font-weight": fontWeight,
"font-family": fontFamily,
"visibility": "hidden" // prevents FOUC
});
// add to body, get width, and get out
$test.appendTo($this.parent());
let width = $test.width();
$test.remove();
// set select width
$this.width(width + arrowWidth);
// run on start
}).change();
});
};
// run by default
$("select.resizeselect").resizeselect();
})
})(jQuery, window);
HTML - Add the class .resizeselect
to any select element:
<select class="btn btn-select <b>resizeselect</b>">
<option>All</option>
<option>Longer</option>
<option>A very very long string...</option>
</select>
JavaScript - Call .resizeselect()
on any jQuery object:
$("select").<b>resizeselect</b>()
(function($, window){
$(function() {
let arrowWidth = 30;
$.fn.resizeselect = function(settings) {
return this.each(function() {
$(this).change(function(){
let $this = $(this);
// get font-weight, font-size, and font-family
let style = window.getComputedStyle(this)
let { fontWeight, fontSize, fontFamily } = style
// create test element
let text = $this.find("option:selected").text();
let $test = $("<span>").html(text).css({
"font-size": fontSize,
"font-weight": fontWeight,
"font-family": fontFamily,
"visibility": "hidden" // prevents FOUC
});
// add to body, get width, and get out
$test.appendTo($this.parent());
let width = $test.width();
$test.remove();
// set select width
$this.width(width + arrowWidth);
// run on start
}).change();
});
};
// run by default
$("select.resizeselect").resizeselect();
})
})(jQuery, window);
.btn-select {
color: #333;
background-color: #f5f5f5;
border-color: #ccc;
padding:7px;
}
<link href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.2/css/bootstrap.css" rel="stylesheet"/>
<link href="//cdnjs.cloudflare.com/ajax/libs/font-awesome/4.3.0/css/font-awesome.css" rel="stylesheet"/>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.2/js/bootstrap.js"></script>
<div class="form-group">
<div class="input-group">
<span class="input-group-btn">
<select class="btn btn-select resizeselect">
<option>All</option>
<option>Longer</option>
<option>A very very long string...</option>
</select>
</span>
<input type="text" class="form-control" placeholder="Search by...">
<span class="input-group-btn">
<button class="btn btn-default" type="button">
<i class="fa fa-search"></i>
</button>
</span>
</div>
</div>
$(function($, window){
,这相当于说$( document ).ready() { (function($, window){
。否则,您的类属性只会在页面上的链接被点击后才会更改(因为文档将在脚本执行后加载)。 - undefinedvar $test = $("<span>").html(text);
更改为var $test = $("<span style=\"font-size:"+$this.css("font-size")+"\">").html(text);
以确保创建的临时span的字体大小与选择元素的字体大小相匹配。如果span的字体大小较小或较大,则动态调整大小将受到大小差异的影响。 - undefinedwindow.getComputedStyle(this)
并将相同的font-weight
、font-size
、font-family
和line-height
分配给span。 - undefined