J'ai cet élément select
avec différents option
dedans. Normalement, l'élément select
tirera sa largeur du plus grand élément option
, mais je veux que l'élément select
ait la largeur par défaut de la valeur option
qui est plus courte . Lorsque l'utilisateur sélectionne un autre option
, l'élément select
doit se redimensionner pour que tout le texte soit toujours visible dans l'élément.
$(document).ready(function() {
$('select').change(function(){
$(this).width($('select option:selected').width());
});
});
Problème:
Vous avez raison, il n'y a aucun moyen facile ou intégré d'obtenir la taille d'une option de sélection particulière. Voici un JsFiddle qui fait ce que vous voulez.
Il est compatible avec les dernières versions de Chrome, Firefox, IE, Opera and Safari
.
J'ai ajouté une sélection masquée #width_tmp_select
pour calculer la largeur du visible sélectionnez #resizing_select
que nous voulons redimensionner automatiquement. Nous définissons la sélection masquée pour avoir une seule option, dont le texte est celui de l'option actuellement sélectionnée de la sélection visible. Ensuite, nous utilisons la largeur de la sélection cachée comme largeur de la sélection visible. Notez que l'utilisation d'une plage masquée au lieu d'une sélection masquée fonctionne plutôt bien, mais la largeur sera un peu décalée comme le souligne sami-al-subhi dans le commentaire ci-dessous.
$(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>
Voici un plugin que je viens d'écrire pour cette question qui crée et détruit dynamiquement une maquette span
pour ne pas encombrer votre html. Cela permet de séparer les préoccupations, vous permet de déléguer cette fonctionnalité et permet une réutilisation facile sur plusieurs éléments.
Incluez ce JS n'importe où:
(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);
Vous pouvez initialiser le plugin de deux manières:
[~ # ~] html [~ # ~] - Ajoutez la classe .resizeselect
à n'importe quel élément de sélection:
<select class="btn btn-select resizeselect">
<option>All</option>
<option>Longer</option>
<option>A very very long string...</option>
</select>
JavaScript - Appelez .resizeselect()
sur n'importe quel objet jQuery:
$("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>
Essayez le simple JavaScript suivant et convertissez-le 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>
Voici un jsfiddle pour cela: https://jsfiddle.net/sm4dnwuf/1/
Fondamentalement, il supprime temporairement les éléments non sélectionnés lorsqu'il n'est pas mis au point (ce qui le redimensionne à la taille de l'élément sélectionné).
Cette solution de travail utilise ici un select
auxiliaire temporaire dans lequel l'option sélectionnée dans la sélection principale est clonée, de sorte que l'on peut évaluer la largeur réelle que le select
principal devrait avoir.
La bonne chose ici est que vous ajoutez simplement ce code et qu'il s'applique à chaque sélection, donc pas besoin de ids
et de noms supplémentaires.
$('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>
Vous pouvez utiliser une fonction 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;
}
Ensuite, utilisez-le simplement sur votre élément de sélection de formulaire:
$(this).getSelectWidth();
Voici encore une autre solution 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);
}
});