我的select
元素中包含不同的option
元素。通常,select
元素会从最大的option
元素获得其宽度,但我希望select
元素的默认option
值的宽度更短。当用户选择另一个option
时,select
元素应自行调整大小,以便整个文本始终在元素中可见。
$(document).ready(function() {
$('select').change(function(){
$(this).width($('select option:selected').width());
});
});
问题:
答案 0 :(得分:39)
你是对的,没有简单或内置的方法来获得特定选择选项的大小。这是JsFiddle,可以满足您的需求。
最新版本的Chrome, Firefox, IE, Opera and Safari
可以。
我添加了一个隐藏的选择#width_tmp_select
来计算我们想要自动调整大小的可见选择#resizing_select
的宽度。我们将隐藏选择设置为具有单个选项,其选项的文本是当前所选选项的选项。然后我们使用隐藏选择的宽度作为可见选择的宽度。请注意,使用隐藏的跨度而不是隐藏的选择效果非常好,但是宽度将稍微偏离,如下面的评论中sami-al-subhi所指出的那样。
$(document).ready(function() {
$('#resizing_select').change(function(){
$("#width_tmp_option").html($('#resizing_select option:selected').text());
$(this).width($("#width_tmp_select").width());
});
});
#resizing_select {
width: 50px;
}
#width_tmp_select{
display : none;
}
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.js"></script>
<select id="resizing_select">
<option>All</option>
<option>Longer</option>
<option>A very very long string...</option>
</select>
<select id="width_tmp_select">
<option id="width_tmp_option"></option>
</select>
答案 1 :(得分:15)
这是我刚为this question编写的一个插件,它动态创建并销毁模拟span
,因此它不会使你的HTML混乱。这有助于区分问题,允许您委派该功能,并允许跨多个元素轻松重用。
将JS放在任何地方:
(function($, window){
var arrowWidth = 30;
$.fn.resizeselect = function(settings) {
return this.each(function() {
$(this).change(function(){
var $this = $(this);
// create test element
var text = $this.find("option:selected").text();
var $test = $("<span>").html(text).css({
"font-size": $this.css("font-size"), // ensures same size text
"visibility": "hidden" // prevents FOUC
});
// add to parent, get width, and get out
$test.appendTo($this.parent());
var 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 - 将班级.resizeselect
添加到任何选择元素:
<select class="btn btn-select resizeselect">
<option>All</option>
<option>Longer</option>
<option>A very very long string...</option>
</select>
JavaScript - 在任何jQuery对象上调用.resizeselect()
:
$("select").resizeselect()
(function($, window){
var arrowWidth = 30;
$.fn.resizeselect = function(settings) {
return this.each(function() {
$(this).change(function(){
var $this = $(this);
// create test element
var text = $this.find("option:selected").text();
var $test = $("<span>").html(text).css({
"font-size": $this.css("font-size"), // ensures same size text
"visibility": "hidden" // prevents FOUC
});
// add to parent, get width, and get out
$test.appendTo($this.parent());
var width = $test.width();
$test.remove();
// set select width
$this.width(width + arrowWidth);
// run on start
}).change();
});
};
// run by default
$("select.resizeselect").resizeselect();
})(jQuery, window);
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.js"></script>
<select class="resizeselect">
<option>All</option>
<option>Longer</option>
<option>A very very long string...</option>
</select>
答案 2 :(得分:3)
尝试以下简单的JavaScript并在jQuery中转换它:)
<html><head><title>Auto size select</title>
<script>
var resized = false;
function resizeSelect(selected) {
if (resized) return;
var sel = document.getElementById('select');
for (var i=0; i<sel.options.length; i++) {
sel.options[i].title=sel.options[i].innerHTML;
if (i!=sel.options.selectedIndex) sel.options[i].innerHTML='';
}
resized = true;
sel.blur();
}
function restoreSelect() {
if (!resized) return;
var sel = document.getElementById('select');
for (var i=0; i<sel.options.length; i++) {
sel.options[i].innerHTML=sel.options[i].title;
}
resized = false;
}
</script>
</head>
<body onload="resizeSelect(this.selectedItem)">
<select id="select"
onchange="resizeSelect(this.selectedItem)"
onblur="resizeSelect(this.selectedItem)"
onfocus="restoreSelect()">
<option>text text</option>
<option>text text text text text</option>
<option>text text text </option>
<option>text text text text </option>
<option>text</option>
<option>text text text text text text text text text</option>
<option>text text</option>
</select>
</body></html>
这是一个jsfiddle:https://jsfiddle.net/sm4dnwuf/1/
基本上它的作用是暂时删除未选中的元素(当它不在焦点上时(使其大小只是所选元素的大小)。
答案 3 :(得分:2)
此工作解决方案在这里利用了一个临时辅助select
,将从主选择中选择的选项克隆到其中,以便人们可以评估主select
应该具有的真实宽度。 / p>
这里的好处是,您只需添加此代码即可,它适用于每个选择,因此无需ids
和额外的命名。
$('select').change(function(){
var text = $(this).find('option:selected').text()
var $aux = $('<select/>').append($('<option/>').text(text))
$(this).after($aux)
$(this).width($aux.width())
$aux.remove()
}).change()
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select>
<option>REALLY LONG TEXT, REALLY LONG TEXT, REALLY LONG TEXT</option>
<option>ABCDEFGHIJKL</option>
<option>ABC</option>
</select>
答案 4 :(得分:1)
您可以使用简单的功能:
// Function that helps to get the select element width.
$.fn.getSelectWidth = function() {
var width = Math.round($(this).wrap('<span></span>').width());
$(this).unwrap();
return width;
}
然后在表单选择元素上使用它:
$(this).getSelectWidth();
答案 5 :(得分:1)
这是另一个简单的jQuery解决方案:
$('#mySelect').change(function(){
var $selectList = $(this);
var $selectedOption = $selectList.children('[value="' + this.value + '"]')
.attr('selected', true);
var selectedIndex = $selectedOption.index();
var $nonSelectedOptions = $selectList.children().not($selectedOption)
.remove()
.attr('selected', false);
// Reset and calculate new fixed width having only selected option as a child
$selectList.width('auto').width($selectList.width());
// Add options back and put selected option in the right place on the list
$selectedOption.remove();
$selectList.append($nonSelectedOptions);
if (selectedIndex >= $nonSelectedOptions.length) {
$selectList.append($selectedOption);
} else {
$selectList.children().eq(selectedIndex).before($selectedOption);
}
});
答案 6 :(得分:0)
这是我实现以下行为的方式:
在文档加载时:所选内容的宽度已经基于所选选项的宽度(不会重新绘制)。
更改时:所选内容的宽度已更新为新选择的选项的宽度。
/* WIDTH, ADJUSTMENT, CONTENT BASED */
$( document ).on( 'change', '.width-content-based', function(){
let text_modified_font;
let text_modified_string;
let descendants_emptied_elements;
text_modified_font =
$( this ).css( 'font-weight' ) + ' ' + $( this ).css( 'font-size' ) + ' ' + $( this ).css( 'font-family' );
if
(
$( this ).is( 'select' )
)
{
text_modified_string =
$( this ).find( ':selected' ).text();
descendants_emptied_elements =
$( this ).find( '[data-text]' );
}
else
{
text_modified_string =
$( this ).val();
}
$( this ).css( { 'width': text_width_estimate( text_modified_string, text_modified_font ) + 'px' } );
if
(
descendants_emptied_elements.length
)
{
descendants_emptied_elements.each( function(){
$( this ).text( $( this ).attr( 'data-text' ) ).removeAttr( 'data-text' );
});
}
});
/* DOCUMENT, ON READY */
$( document ).ready( function(){
$( '.width-content-based' ).trigger( 'change' );
});
/* TEXT WIDTH ESTIMATE */ function text_width_estimate( text, font ) { let canvas = text_width_estimate.canvas || ( text_width_estimate.canvas = document.createElement( 'canvas' ) ); let context = canvas.getContext( '2d' ); context.font = font; let metrics = context.measureText( text ); return metrics.width + 3; }
select { -webkit-appearance: none; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select class="width-content-based">
<option value="AF" data-text="Afghanistan"></option>
<option value="AX" data-text="Åland Islands"></option>
<option value="AL" selected>Albania</option>
</select>
答案 7 :(得分:0)
这里有一个更现代的 vanilla JS 方法来解决这个问题。它或多或少与 this answer 中的原理相同,只是没有 jQuery。
selectedIndex
的文本传递给该选项。position: fixed
和 visibility: hidden
样式。这可确保它不会影响您的布局,但仍可测量其边界框。getBoundingClientRect().width
const select = document.querySelector('select')
select.addEventListener('change', (event) => {
let tempSelect = document.createElement('select'),
tempOption = document.createElement('option');
tempOption.textContent = event.target.options[event.target.selectedIndex].text;
tempSelect.style.cssText += `
visibility: hidden;
position: fixed;
`;
tempSelect.appendChild(tempOption);
event.target.after(tempSelect);
const tempSelectWidth = tempSelect.getBoundingClientRect().width;
event.target.style.width = `${tempSelectWidth}px`;
tempSelect.remove();
});
select.dispatchEvent(new Event('change'));
<select>
<option>Short option</option>
<option>Some longer option</option>
<option>An very long option with a lot of text</option>
</select>
答案 8 :(得分:0)
这里有一个示例,它从自动调整大小的选择框开始,然后在选择新框时如何自动调整宽度。
只需将其复制并粘贴到 Visual Studio 代码文档中,并将其命名为 index.html 并双击该文件(对于超级菜鸟)。
$(document).ready(function() {
// Auto set the width of the select box for Manufacture on startup
$("#width_tmp_option").html($('#Manufacture')[0][0].label);
$('#Manufacture').width($('#width_tmp_select').width());
// Adust the width of the select box each time Manufacture is changed
$('#Manufacture').change(function(){
$("#width_tmp_option").html($('#Manufacture option:selected').text());
$(this).width($("#width_tmp_select").width());
});
});
#Manufacture {
font-size:17px;
}
#width_tmp_select{
display : none;
font-size:17px;
}
<!-- JS (Jquery) -->
<script src="https://code.jquery.com/jquery-3.6.0.js"
integrity="sha256-H+K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk="
crossorigin="anonymous"></script>
<!-- HTML -->
<!-- These are hidden dummy selects that I use to store some html in them and then retrieve the width to resize my select boxes. -->
<select id="width_tmp_select">
<option id="width_tmp_option"></option>
</select>
<select id="Manufacture">
<option>Toyota</option>
<option>Ford</option>
<option>Lamborghini</option>
</select>
答案 9 :(得分:-3)
你也可以尝试这个
select option{width:0; }
select option:hover{width:auto;}