jquery - texto - Cambio de tamaño automático del elemento SELECT según el ancho de la OPCIÓN seleccionada
select multiple html ejemplo (6)
Puedes probar esto también
select option{width:0; }
select option:hover{width:auto;}
Tengo este elemento select
con una option
diferente. Normalmente, el elemento select
obtendría su ancho del elemento de option
más grande, pero quiero que el elemento de select
tenga el ancho del valor de la option
predeterminada, que es más corto. Cuando el usuario selecciona otra option
, el elemento de select
debe redimensionarse para que todo el texto esté siempre visible en el elemento.
$(document).ready(function() {
$(''select'').change(function(){
$(this).width($(''select option:selected'').width());
});
});
Problema:
- En Chrome (Canary) siempre obtiene un ancho devuelto de 0.
- En Firefox, se agrega el ancho y no se redimensiona cuando se selecciona una opción más corta.
- Safari: el mismo resultado que Chrome.
Estás en lo cierto: no hay una manera fácil o integrada de obtener el tamaño de una opción de selección en particular. Aquí hay un JsFiddle que hace lo que quiere.
Está bien con las últimas versiones de Chrome, Firefox, IE, Opera and Safari
.
He agregado una selección oculta #width_tmp_select
para calcular el ancho de la selección visible #resizing_select
que queremos cambiar automáticamente el tamaño. Configuramos la selección oculta para que tenga una sola opción, cuyo texto es el de la opción actualmente seleccionada de la selección visible. Luego usamos el ancho de la selección oculta como el ancho de la selección visible. Tenga en cuenta que el uso de un intervalo oculto en lugar de un elemento oculto funciona bastante bien, pero el ancho será un poco fuera de lo señalado por sami-al-subhi en el comentario a continuación.
$(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>
Pruebe el siguiente JavaScript simple y conviértalo en 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>
Aquí hay un jsfiddle para ello: https://jsfiddle.net/sm4dnwuf/1/
Básicamente, lo que hace es eliminar temporalmente los elementos no seleccionados cuando no está enfocado (haciendo que su tamaño se limite al tamaño del seleccionado).
Puedes usar una función simple:
// 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;
}
Entonces solo utilícelo en su elemento de selección de formulario:
$(this).getSelectWidth();
Aquí hay un complemento que acabo de escribir para esta pregunta que crea dinámicamente y destruye un span
simulado para que no ocupe demasiado tu html. Esto ayuda a separar las preocupaciones, le permite delegar esa funcionalidad y permite una fácil reutilización en múltiples elementos.
Incluye este JS en cualquier lugar:
(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);
Puede inicializar el complemento de una de estas dos formas:
HTML - Agregue la clase
.resizeselect
a cualquier elemento seleccionado:<select class="btn btn-select resizeselect"> <option>All</option> <option>Longer</option> <option>A very very long string...</option> </select>
JavaScript - Llame a
.resizeselect()
en cualquier objeto jQuery:$("select").resizeselect()
Aquí hay una demostración en jsFiddle
Aquí hay una demostración en Stack Snippets:
(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>
Actualizado para incluir sugerencias de tamaño de Garywoo y Eric Warnke
Aquí hay otra solución jQuery simple:
$(''#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);
}
});