web-dev-qa-db-fra.com

Largeur de la liste déroulante dans IE

Dans IE, la liste déroulante prend la même largeur que la liste déroulante (j'espère que cela a du sens), tandis que dans Firefox, la largeur de la liste déroulante varie en fonction du contenu.

Cela signifie en gros que je dois m'assurer que la liste déroulante est suffisamment large pour afficher la sélection la plus longue possible. Cela rend ma page très moche :(

Existe-t-il une solution de contournement à ce problème? Comment utiliser CSS pour définir différentes largeurs pour la liste déroulante et la liste déroulante?

92
Nimesh Madhavan

Voici un autre exemple basé sur jQuery . Contrairement à toutes les autres réponses publiées ici, il prend en compte tous les événements liés au clavier et à la souris, notamment les clics:

if (!$.support.leadingWhitespace) { // if IE6/7/8
    $('select.wide')
        .bind('focus mouseover', function() { $(this).addClass('expand').removeClass('clicked'); })
        .bind('click', function() { $(this).toggleClass('clicked'); })
        .bind('mouseout', function() { if (!$(this).hasClass('clicked')) { $(this).removeClass('expand'); }})
        .bind('blur', function() { $(this).removeClass('expand clicked'); });
}

Utilisez-le en combinaison avec ce morceau de CSS:

select {
    width: 150px; /* Or whatever width you want. */
}
select.expand {
    width: auto;
}

Tout ce que vous avez à faire est d’ajouter la classe wide au (x) élément (s) de liste déroulante en question.

<select class="wide">
    ...
</select>

Voici un exemple jsfiddle . J'espère que cela t'aides.

102
BalusC

Créer votre propre liste déroulante est plus pénible que ça ne vaut la peine. Vous pouvez utiliser du JavaScript pour que le menu déroulant IE) fonctionne.

Il utilise un peu de la bibliothèque YUI et une extension spéciale pour la correction des cases IE).

Vous devrez inclure ce qui suit et envelopper votre <select> éléments dans un <span class="select-box">

Placez-les avant la balise body de votre page:

<script src="http://us.js2.yimg.com/us.js.yimg.com/lib/common/utils/2/yahoo_2.0.0-b3.js" type="text/javascript">
</script>
<script src="http://us.js2.yimg.com/us.js.yimg.com/lib/common/utils/2/event_2.0.0-b3.js" type="text/javascript">
</script>
<script src="http://us.js2.yimg.com/us.js.yimg.com/lib/common/utils/2/dom_2.0.2-b3.js" type="text/javascript">
</script>
<script src="ie-select-width-fix.js" type="text/javascript">
</script>
<script>
// for each select box you want to affect, apply this:
var s1 = new YAHOO.Hack.FixIESelectWidth( 's1' ); // s1 is the ID of the select box you want to affect
</script>

Après acceptation éditer:

Vous pouvez également le faire sans la bibliothèque YUI et le contrôle Hack. Tout ce que vous avez vraiment besoin de faire est de mettre onmouseover = "this.style.width = 'auto'" onmouseout = "this.style.width = '100px'" (ou ce que vous voulez) sur l'élément select. Le contrôle YUI lui donne cette belle animation mais ce n’est pas nécessaire. Cette tâche peut également être accomplie avec jquery et d'autres bibliothèques (bien que je n'ai pas trouvé de documentation explicite à ce sujet)

- amendement à la modification:
IE a un problème avec onmouseout pour les contrôles de sélection (il ne considère pas que le survol des options est un survol de la sélection). Cela rend l'utilisation de la souris très délicate. La première solution est la meilleure que j'ai trouvée jusqu'à présent.

14

vous pouvez juste essayer ce qui suit ...

  styleClass="someStyleWidth"
  onmousedown="javascript:if(navigator.appName=='Microsoft Internet Explorer'){this.style.position='absolute';this.style.width='auto'}" 
  onblur="this.style.position='';this.style.width=''"

J'ai essayé et ça marche pour moi. Rien d'autre n'est requis.

12
Sai

J'ai utilisé la solution suivante et cela semble bien fonctionner dans la plupart des situations.

<style>
select{width:100px}
</style>

<html>
<select onmousedown="if($.browser.msie){this.style.position='absolute';this.style.width='auto'}" onblur="this.style.position='';this.style.width=''">
  <option>One</option>
  <option>Two - A long option that gets cut off in IE</option>
</select>
</html>

Remarque: le $. Browser.msie nécessite jquery.

9
Justin Fisher

@Vous avez également besoin d'ajouter un gestionnaire d'événements Blur

$(document).ready(function(){
    $("#dropdown").mousedown(function(){
        if($.browser.msie) {
            $(this).css("width","auto");
        }
    });
    $("#dropdown").change(function(){
        if ($.browser.msie) {
            $(this).css("width","175px");
        }
    });
    $("#dropdown").blur(function(){
        if ($.browser.msie) {
            $(this).css("width","175px");
        }
    });
});

Cependant, cela élargira toujours la zone de sélection en cliquant, au lieu de simplement les éléments. (et cela semble échouer dans IE6, mais fonctionne parfaitement dans Chrome et IE7)

7
Tinus

Si vous utilisez jQuery, alors essayez ce plugin IE select width:

http://www.jainaewen.com/files/javascript/jquery/ie-select-style/

En appliquant ce plugin, la zone de sélection dans Internet Explorer semble fonctionner de la même manière que dans Firefox, Opera, etc.) en permettant aux éléments d’option de s’ouvrir sur toute la largeur sans perdre l’aspect et le style de la correction. Il ajoute également la prise en charge du remplissage et des bordures de la zone de sélection dans Internet Explorer 6 et 7.

5
Ewen

Il n'y a aucun moyen de le faire dans IE6/IE7/IE8. Le contrôle est dessiné par l'application et IE ne le dessine tout simplement pas de cette façon. Votre meilleur pari est d'implémenter votre propre liste déroulante via HTML/CSS/JavaScript si c'est ce qui importe le plus. avoir le la liste déroulante une largeur et la liste une autre largeur.

5
Robert C. Barth

Dans jQuery cela fonctionne assez bien. Supposons que la liste déroulante a id = "dropdown".

$(document).ready(function(){

    $("#dropdown").mousedown(function(){
    if($.browser.msie) {
        $(this).css("width","auto");
    }
    });
    $("#dropdown").change(function(){
    if ($.browser.msie) {
        $(this).css("width","175px");
    }
    });

});
4
Thad

Voici la solution la plus simple.

Avant de commencer, je dois vous dire que la liste déroulante de sélection s’étendra automatiquement dans presque tous les navigateurs sauf IE6. Donc, je voudrais faire une vérification du navigateur (c'est-à-dire, IE6) et écrire ce qui suit uniquement pour ce navigateur. Ici ça va. Commencez par vérifier le navigateur.

Le code étendra comme par magie la liste de sélection déroulante. Le seul problème avec la solution est onmouseover la liste déroulante sera étendue à 420px, et parce que le débordement = masqué, nous masquons la taille de la liste déroulante étendue et l’affiche sous 170px; ainsi, la flèche à droite du ddl sera cachée et ne pourra pas être vue. mais la zone de sélection sera étendue à 420px; c'est ce que nous voulons vraiment. Essayez juste le code ci-dessous et utilisez-le si vous l’aimez.

.ctrDropDown
{
    width:420px; <%--this is the actual width of the dropdown list--%>
}
.ctrDropDownClick
{
    width:420px; <%-- this the width of the dropdown select box.--%>
}

<div style="width:170px; overflow:hidden;">
<asp:DropDownList runat="server" ID="ddlApplication" onmouseout = "this.className='ctrDropDown';" onmouseover ="this.className='ctrDropDownClick';" class="ctrDropDown" onBlur="this.className='ctrDropDown';" onMouseDown="this.className='ctrDropDownClick';" onChange="this.className='ctrDropDown';"></asp:DropDownList>
</div>

Ce qui précède est le CSS IE6. Le CSS commun à tous les autres navigateurs devrait être comme ci-dessous.

.ctrDropDown
{
    width:170px; <%--this is the actual width of the dropdown list--%>
}
.ctrDropDownClick
{
    width:auto; <%-- this the width of the dropdown select box.--%>
}
3
bluwater2001

check this out .. ce n'est pas parfait mais ça marche et c'est pour IE seulement et n'affecte pas FF. J'ai utilisé le javascript habituel pour onmousedown pour établir IE = seulement correct .. mais le msie de jQuery pourrait être utilisé aussi bien dans le onmousedown .. l'idée principale est le "onchange" et sur le flou pour que la zone de sélection revienne à la normale ... décidez que vous avez votre propre largeur pour ceux J'avais besoin de 35%.

onmousedown="javascript:if(navigator.appName=='Microsoft Internet Explorer'){this.style.width='auto'}" 
onchange="this.style.width='35%'"
onblur="this.style.width='35%'"
2
lucien

si vous voulez un menu déroulant et/ou un menu déroulant sans effets de transition, utilisez simplement CSS ... vous pouvez forcer IE6 à prendre en charge: survolez tous les éléments à l'aide d'un fichier .htc (css3hover?) avec le comportement (propriété IE6 uniquement) défini dans le fichier CSS attaché sous condition.

2
cam

La réponse de BalusC ci-dessus fonctionne très bien, mais il y a une petite solution que je voudrais ajouter si le contenu de votre liste déroulante a une largeur inférieure à celle que vous définissez dans votre select.expand CSS, ajoutez ceci à la reliure mouseover:

.bind('mouseover', function() { $(this).addClass('expand').removeClass('clicked');
                                if ($(this).width() < 300) // put your desired minwidth here
                                {
                                    $(this).removeClass('expand');
                                }})
2
jbabey

C’est quelque chose que j’ai fait en prenant des bribes des affaires d’autres personnes.

        $(document).ready(function () {
        if (document.all) {

            $('#<%=cboDisability.ClientID %>').mousedown(function () {
                $('#<%=cboDisability.ClientID %>').css({ 'width': 'auto' });
            });

            $('#<%=cboDisability.ClientID %>').blur(function () {
                $(this).css({ 'width': '208px' });
            });

            $('#<%=cboDisability.ClientID %>').change(function () {
                $('#<%=cboDisability.ClientID %>').css({ 'width': '208px' });
            });

            $('#<%=cboEthnicity.ClientID %>').mousedown(function () {
                $('#<%=cboEthnicity.ClientID %>').css({ 'width': 'auto' });
            });

            $('#<%=cboEthnicity.ClientID %>').blur(function () {
                $(this).css({ 'width': '208px' });
            });

            $('#<%=cboEthnicity.ClientID %>').change(function () {
                $('#<%=cboEthnicity.ClientID %>').css({ 'width': '208px' });
            });

        }
    });

où cboEthnicity et cboDisability sont des menus déroulants avec un texte d’option plus large que la largeur de la sélection elle-même.

Comme vous pouvez le constater, j’ai spécifié document.all car cela ne fonctionne que dans IE. De plus, j'ai inséré les listes déroulantes dans des éléments div comme ceci:

<div id="dvEthnicity" style="width: 208px; overflow: hidden; position: relative; float: right;"><asp:DropDownList CssClass="select" ID="cboEthnicity" runat="server" DataTextField="description" DataValueField="id" Width="200px"></asp:DropDownList></div>

Cela évite que les autres éléments ne se déplacent pas lorsque votre liste déroulante se développe. Le seul inconvénient ici est que le visuel de la ménuliste disparaît lorsque vous sélectionnez mais revient dès que vous avez sélectionné.

J'espère que ça aide quelqu'un.

2
Derrick

c'est la meilleure façon de faire ceci:

select:focus{
    min-width:165px;
    width:auto;
    z-index:9999999999;
    position:absolute;
}

c'est exactement la même chose que la solution BalusC. Seulement c'est plus facile. ;)

2
mcmwhfy

Un plugin complet jQuery est disponible. Il prend en charge la mise en page et les interactions au clavier, consultez la page de démonstration: http://powerkiki.github.com/ie_expand_select_width/

disclaimer: J'ai codé cette chose, les correctifs sont les bienvenus

2
PowerKiKi
1
Ybbest

La solution de jquery BalusC a été améliorée par moi. Utilisé aussi: Brad Robertson's commentez ici .

Il suffit de mettre cela dans un fichier .js, d’utiliser la classe wide pour les combinaisons désirées et de ne pas forger pour lui attribuer un identifiant. Appelez la fonction dans le onload (ou documentReady ou autre).
Aussi simple que ça :)
Il utilisera la largeur que vous avez définie pour le combo comme longueur minimale.

function fixIeCombos() {
    if ($.browser.msie && $.browser.version < 9) {
    var style = $('<style>select.expand { width: auto; }</style>');
    $('html > head').append(style);

    var defaultWidth = "200";

    // get predefined combo's widths.
    var widths = new Array();
    $('select.wide').each(function() {
        var width = $(this).width();
        if (!width) {
        width = defaultWidth;
        }
        widths[$(this).attr('id')] = width;
    });

    $('select.wide')
    .bind('focus mouseover', function() {
        // We're going to do the expansion only if the resultant size is bigger
        // than the original size of the combo.
        // In order to find out the resultant size, we first clon the combo as
        // a hidden element, add to the dom, and then test the width.
        var originalWidth = widths[$(this).attr('id')];

        var $selectClone = $(this).clone();
        $selectClone.addClass('expand').hide();
        $(this).after( $selectClone );
        var expandedWidth = $selectClone.width()
        $selectClone.remove();
        if (expandedWidth > originalWidth) {
        $(this).addClass('expand').removeClass('clicked');
        }
    })
    .bind('click', function() {
        $(this).toggleClass('clicked'); 
    })
    .bind('mouseout', function() {
        if (!$(this).hasClass('clicked')) {
        $(this).removeClass('expand');
        }
    })
    .bind('blur', function() {
        $(this).removeClass('expand clicked');
    })
    }
}
1
Federico Valido

J'ai essayé toutes ces solutions et aucune ne fonctionnait complètement pour moi. C'est ce que je suis venu avec

$(document).ready(function () {

var clicknum = 0;

$('.dropdown').click(
        function() {
            clicknum++;
            if (clicknum == 2) {
                clicknum = 0;
                $(this).css('position', '');
                $(this).css('width', '');
            }
        }).blur(
        function() {
            $(this).css('position', '');
            $(this).css('width', '');
            clicknum = 0;
        }).focus(
        function() {
            $(this).css('position', 'relative');
            $(this).css('width', 'auto');
        }).mousedown(
        function() {
            $(this).css('position', 'relative');
            $(this).css('width', 'auto');
        });
})(jQuery);

Assurez-vous d’ajouter une classe de liste déroulante à chaque liste déroulante dans votre code HTML.

L'astuce consiste ici à utiliser la fonction de clic spécialisée (je l'ai trouvée ici événement Fire chaque fois qu'un élément DropDownList est sélectionné avec jQuery ). La plupart des autres solutions proposées ici utilisent la modification du gestionnaire d'événements, qui fonctionne correctement mais ne se déclenche pas si l'utilisateur sélectionne la même option que celle sélectionnée précédemment.

Comme beaucoup d’autres solutions, la focalisation et le survol de souris s’appliquent lorsque l’utilisateur place la liste déroulante au premier plan, tandis que le flou s’applique au cliquetis.

Vous voudrez peut-être également y insérer une sorte de détection de navigateur afin que seuls les effets soient atteints. Cela n'a pas l'air mal dans les autres navigateurs

0
RasTheDestroyer

Cela semble fonctionner avec IE6 et ne semble pas en casser d'autres. L’autre particularité de Nice est que le menu est modifié automatiquement dès que vous modifiez la liste déroulante.

$(document).ready(function(){
    $("#dropdown").mouseover(function(){
        if($.browser.msie) {
            $(this).css("width","auto");
        }
    });
    $("#dropdown").change(function(){
        if ($.browser.msie) {
            $("#dropdown").trigger("mouseover");
        }
    });

});
0
lhoess

Basé sur la solution publiée par Sai , voici comment procéder avec jQuery.

$(document).ready(function() {
    if ($.browser.msie) $('select.wide')
        .bind('onmousedown', function() { $(this).css({position:'absolute',width:'auto'}); })
        .bind('blur', function() { $(this).css({position:'static',width:''}); });
});
0
Ahmad Alfy

Nous avons la même chose sur un asp: dropdownlist:

Dans Firefox (3.0.5), la liste déroulante correspond à la largeur de l'élément le plus long dans la liste déroulante, soit 600 pixels de large ou quelque chose du genre.

0
Harlequin

Vous pouvez ajouter un style directement à l'élément select:

<select name="foo" style="width: 200px">

Donc, cet élément sélectionné aura une largeur de 200 pixels.

Vous pouvez également appliquer une classe ou un identifiant à l'élément et le référencer dans une feuille de style.

0
Katy

Le lien hedgerwow (la solution d’animation YUI) dans la première réponse est cassé, je suppose que le domaine a expiré. J'ai copié le code avant son expiration pour que vous puissiez le trouver ici (le propriétaire du code peut me faire savoir si je ne respecte pas les droits d'auteur en le téléchargeant à nouveau)

http://ciitronian.com/blog/programming/yui-button-mimicking-native-select-dropdown-avoid-width-problem/

Sur le même article de blog, j’ai écrit à propos de la création d’un élément SELECT identique à celui qui est normal à l’aide du menu Bouton YUI. Regardez et laissez-moi savoir si cela aide!

0
Hammad Tariq

Jusqu'à présent, il n'y en a pas. Je ne connais pas IE8, mais cela ne peut être fait dans IE6 et IE7 que si vous implémentez votre propre fonctionnalité de liste déroulante avec javascript. Il existe des exemples sur la manière de le faire sur le Web, bien que je ne voie pas grand avantage à la duplication de fonctionnalités existantes.

0
pilsetnieks

Son testé dans toutes les versions de IE, Chrome, FF et Safari

// code JavaScript

<script type="text/javascript">
<!-- begin hiding
function expandSELECT(sel) {
  sel.style.width = '';
}
function contractSELECT(sel) {
  sel.style.width = '100px';
}
// end hiding -->
</script>

// Code HTML

<select name="sideeffect" id="sideeffect"  style="width:100px;" onfocus="expandSELECT(this);" onblur="contractSELECT(this);" >
  <option value="0" selected="selected" readonly="readonly">Select</option>
<option value="1" >Apple</option>
<option value="2" >Orange + Banana + Grapes</option>
0
Arif

J'ai dû contourner ce problème et proposer une fois une solution assez complète et évolutive fonctionnant pour IE6, 7 et 8 (et compatible avec d'autres navigateurs évidemment). J'ai écrit tout un article à ce sujet ici même: http://www.edgeoftheworld.fr/wp/work/dealing-with-fixed-sized-dropdown-lists-in-internet-Explorer

Je pensais partager cela pour les personnes qui rencontrent encore ce problème, car aucune des solutions ci-dessus ne fonctionne dans tous les cas (à mon avis).

0
Aerendel

Je pensais jeter mon chapeau dans le ring. Je crée une application SaaS) et un menu de sélection est intégré dans une table. Cette méthode a fonctionné, mais elle a faussé tout le contenu de la table.

onmousedown="if(navigator.appName=='Microsoft Internet Explorer'){this.style.position='absolute';this.style.width='auto'}
onblur="if(navigator.appName=='Microsoft Internet Explorer'){this.style.position=''; this.style.width= '225px';}"

Donc, ce que j’ai fait pour améliorer la situation, c’est de jeter la sélection dans un div indexé en z.

<td valign="top" style="width:225px; overflow:hidden;">
    <div style="position: absolute; z-index: 5;" onmousedown="var select = document.getElementById('select'); if(navigator.appName=='Microsoft Internet Explorer'){select.style.position='absolute';select.style.width='auto'}">
        <select name="select_name" id="select" style="width: 225px;" onblur="if(navigator.appName=='Microsoft Internet Explorer'){this.style.position=''; this.style.width= '225px';}" onChange="reportFormValues('filter_<?=$job_id?>','form_values')">
            <option value="0">All</option>
            <!--More Options-->
        </select>
    </div>
</td>
0
n0nag0n