Автоматическое изменение размера элемента SELECT в соответствии с шириной выбранного параметра
у меня есть select
элемент с различными option
в нем. Обычно select
элемент получит свою ширину от самого большого option
элемент, но я хочу, чтобы select
элемент по умолчанию option
ширина значения, которая короче. Когда пользователь выбирает другой option
на select
элемент должен изменять размер, чтобы весь текст всегда был виден в элементе.
$(document).ready(function() {
$('select').change(function(){
$(this).width($('select option:selected').width());
});
});
:
- на Chrome (Canary) он всегда получает ширину вернулся из 0.
- в Firefox ширина get добавлена и не изменяется при выборе более короткой опции.
- Safari: тот же результат, что и Chrome.
Демо - @ JSFiddle
6 ответов
вы правы, нет простого или встроенного способа получить размер конкретной опции выбора. Вот это JsFiddle что делает то, что вы хотите.
это нормально с последними версиями Chrome, Firefox, IE, Opera and Safari
.
я добавил скрытый выберите #width_tmp_select
для вычисления ширины видимого выберите #resizing_select
что мы хотим быть автоматическое изменение размера. Мы устанавливаем скрытый выбор для одного параметра, текст которого является текстом выбранного в данный момент параметра видимого выбора. Затем мы используем ширину скрытого выбора как ширину видимого выбора. Обратите внимание, что использование скрытого диапазона вместо скрытого выбора работает довольно хорошо, но ширина будет немного выключена, как указано Сами-аль-Субхи в комментарии ниже.
$(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>
вот плагин, который я только что написал для этот вопрос это динамически создает и уничтожает макет 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 - вызов
.resizeselect()
на любом объекте jQuery:$("select").resizeselect()
здесь демо на jsFiddle
вот демонстрация в фрагментах стека:
(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>
обновлено, чтобы включить предложения по размеру от Garywoo & Эрик Warnke
попробуйте следующий простой 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/
в основном то, что он делает, временно удаляет невыбранные элементы, когда он не находится в фокусе (вызывая его размер до размера выбранного).
Вы можете использовать простую функцию:
// 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();
вот еще одно простое решение на 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);
}
});