Solución:
Tiene razón, no hay una forma fácil o incorporada 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 de tamaño automáticamente. 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 usar un intervalo oculto en lugar de una selección oculta funciona bastante bien, pero el ancho será un poco desviado, como lo señala 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="https://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>
Aquí hay un complemento que acabo de escribir para esta pregunta que crea y destruye dinámicamente un simulacro span
para que no abarrote su html. Esto ayuda a separar las preocupaciones, le permite delegar esa funcionalidad y permite una fácil reutilización en múltiples elementos.
Incluya 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 – Agregar 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 – Llama
.resizeselect()
en cualquier objeto jQuery:$("select").resizeselect()
Aquí hay una demostración en jsFiddle
Aquí hay una demostración en fragmentos de pila:
(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="https://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
Esta solución de trabajo hace uso aquí de un auxiliar temporal. select
en el que se clona la opción seleccionada de la selección principal, de modo que se puede evaluar el ancho real que el principal select
debería tener.
Lo bueno aquí es que simplemente agrega este código y es aplicable a todas las selecciones, por lo que no es necesario ids
y nombres adicionales.
$('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>