Largura da lista suspensa no IE

92

No IE, a lista suspensa tem a mesma largura que a caixa suspensa (espero estar fazendo sentido), enquanto no Firefox a largura da lista suspensa varia de acordo com o conteúdo.

Basicamente, isso significa que preciso ter certeza de que a caixa de depósito é grande o suficiente para exibir a seleção mais longa possível. Isso deixa minha página muito feia :(

Existe alguma solução alternativa para esse problema? Como posso usar CSS para definir larguras diferentes para a caixa de depósito e a lista suspensa?

Nimesh Madhavan
fonte

Respostas:

102

Aqui está outro exemplo baseado em jQuery . Ao contrário de todas as outras respostas postadas aqui, todos os eventos de teclado e mouse são levados em consideração, especialmente os cliques:

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'); });
}

Use-o em combinação com este pedaço de CSS:

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

Tudo o que você precisa fazer é adicionar a classe wideao (s) elemento (s) suspenso (s) em questão.

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

Aqui está um exemplo jsfiddle . Espero que isto ajude.

BalusC
fonte
2
+1: De todas as soluções propostas aqui, esta funcionou melhor para mim. Também precisei fazer alterações em CSS e HTML para que funcionasse no meu caso. Tanto trabalho para algo que deveria funcionar fora da caixa.
kgiannakakis
1
Funciona com o IE7, não no IE6 - há algum ajuste para o IE6?
DM em
4
@DMin: Desculpe, não oferecemos suporte a navegadores antigos e obsoletos como o IE6.
BalusC de
3
@BalusC: :) Eu sei que meu amigo IE é uma merda - apesar de tudo, usei sua resposta, funcionou para o IE7 - escreveu um código separado para o IE6 que incluía sua resposta + bind. ('Mouseenter' .. - funcionou bem - Obrigado de qualquer maneira! :)
DMin
3
Dependendo de suas outras regras de CSS - talvez você precise adicionar! Importante para a largura ..width: auto !important;
Tapirboy
14

Criar sua própria lista suspensa é mais trabalhoso do que vale a pena. Você pode usar algum JavaScript para fazer o menu suspenso do IE funcionar.

Ele usa um pouco da biblioteca YUI e uma extensão especial para corrigir as caixas de seleção do IE.

Você precisará incluir o seguinte e envolver seus <select>elementos em um<span class="select-box">

Coloque-os antes da tag do corpo da sua página:

<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>

Edição de aceitação da postagem:

Você também pode fazer isso sem a biblioteca YUI e o controle de hack. Tudo o que você realmente precisa fazer é colocar onmouseover = "this.style.width = 'auto'" onmouseout = "this.style.width = '100px'" (ou o que você quiser) no elemento selecionado. O controle YUI oferece uma boa animação, mas não é necessário. Esta tarefa também pode ser realizada com jquery e outras bibliotecas (embora eu não tenha encontrado documentação explícita para isso)

- alteração à edição: o
IE tem um problema com o onmouseout para controles de seleção (não considera o mouseover nas opções sendo um mouseover no select). Isso torna o uso do mouseout muito complicado. A primeira solução é a melhor que encontrei até agora.

Ninja da privação do sono
fonte
3
Recebo um 404 em ambos os links
Chris B
O problema com essa correção é se você tiver seleções dinâmicas, digamos, em um aplicativo de comércio eletrônico para atributos de produto. Você nunca vai saber os IDs de todos os
menus
1
Os links não são mais 404, mas mostram o que considero spam malicioso. Eu considerei uma votação negativa, mas serei gentil e apenas indicarei.
davur
12

você pode apenas tentar o seguinte ...

  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=''"

Eu tentei e funcionou para mim. Nada mais é necessário.

Sai
fonte
1
Legal, eu melhorei um pouco (usando comentário condicional para detecção do IE) e adicionei alguns comentários, ele funciona muito bem e sem jQuery ou outras bibliotecas. Veja aqui: jsbin.com/ubahe5/edit - plz EDITAR sua resposta que QUERO TE DAR +1, mas não posso porque votei errado antes.
Marco Demaio
9

Usei a solução a seguir e parece funcionar bem na maioria das situações.

<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>

Nota: o $ .browser.msie requer jquery.

Justin Fisher
fonte
Para qualquer outra pessoa que esteja com sono que deveria estar onmousedown, não onmousdown - levei alguns minutos para ver o problema
shearichard
7

@Thad você precisa adicionar um manipulador de eventos de desfoque também

$(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");
        }
    });
});

No entanto, isso ainda expandirá a caixa de seleção ao clicar, em vez de apenas os elementos. (e parece falhar no IE6, mas funciona perfeitamente no Chrome e no IE7)

Tinus
fonte
5

Não há como fazer isso no IE6 / IE7 / IE8. O controle é desenhado pelo aplicativo e o IE simplesmente não o desenha dessa maneira. Sua melhor aposta é implementar seu próprio menu suspenso via HTML / CSS / JavaScript simples se for tão importante ter o menu suspenso com uma largura e a lista com outra largura.

Robert C. Barth
fonte
a solução é: use javascript e css para ajustar automaticamente a largura ao passar o mouse (e outros eventos de teclado ...). leia aqui: css-tricks.com/select-cuts-off-options-in-ie-fix a melhor solução (menos invasivo)
tuffo19
5

Se você usa jQuery, experimente este plugin de largura de seleção do IE:

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

A aplicação deste plugin faz com que a caixa de seleção no Internet Explorer pareça funcionar como funcionaria no Firefox, Opera etc, permitindo que os elementos de opção abram na largura total sem perder a aparência e o estilo da largura fixa. Ele também adiciona suporte para preenchimento e bordas na caixa de seleção no Internet Explorer 6 e 7.

Ewen
fonte
4

Em jQuery, isso funciona muito bem. Suponha que o menu suspenso tenha id = "suspenso".

$(document).ready(function(){

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

});
Eran Medan
fonte
3

Aqui está a solução mais simples.

Antes de começar, devo dizer que a caixa de seleção suspensa se expandirá automaticamente em quase todos os navegadores, exceto no IE6. Portanto, eu faria uma verificação do navegador (ou seja, IE6) e escreveria o seguinte apenas nesse navegador. Aqui vai. Primeiro verifique o navegador.

O código irá expandir magicamente a caixa de seleção suspensa. O único problema com a solução é onmouseover, o menu suspenso será expandido para 420px e, como overflow = hidden, estamos ocultando o tamanho do menu suspenso expandido e mostrando-o como 170px; portanto, a seta do lado direito do ddl ficará oculta e não poderá ser vista. mas a caixa de seleção será expandida para 420px; que é o que realmente queremos. Experimente o código abaixo e use-o se desejar.

.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>

O código acima é o CSS do IE6. O CSS comum para todos os outros navegadores deve ser o seguinte.

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

se você quiser um menu suspenso e / ou flyout simples sem efeitos de transição, use CSS ... você pode forçar o IE6 a suportar: passar o mouse sobre todos os elementos usando um arquivo .htc (css3hover?) com comportamento (propriedade apenas do IE6) definido em o arquivo CSS anexado condicionalmente.

cam
fonte
2

verifique isso .. não é perfeito, mas funciona e é apenas para o IE e não afeta o FF. Eu usei o javascript regular para onmousedown para estabelecer a correção somente do IE .. mas o msie do jquery pode ser usado também no onmousedown .. a ideia principal é "onchange" e on blur para que a caixa de seleção volte ao normal .. decidir que você tem largura própria para aqueles. Eu precisava de 35%.

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

A resposta de BalusC acima funciona muito bem, mas há uma pequena correção que eu acrescentaria se o conteúdo de sua lista suspensa tiver uma largura menor do que a que você define em seu CSS select.expand, adicione isso ao link mouseover:

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

Isso é algo que fiz retirando pedaços das coisas de outras pessoas.

        $(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' });
            });

        }
    });

onde cboEthnicity e cboDisability são menus suspensos com o texto da opção mais largo do que a largura do próprio select.

Como você pode ver, especifiquei document.all, pois isso só funciona no IE. Além disso, envolvi os menus suspensos em elementos div como este:

<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>

Isso faz com que os outros elementos saiam do lugar quando o menu suspenso se expande. A única desvantagem aqui é que o visual do menulista desaparece quando você está selecionando, mas retorna assim que você seleciona.

Espero que isso ajude alguém.

Torre
fonte
2

esta é a melhor maneira de fazer isso:

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

é exatamente igual à solução BalusC. Só isso é mais fácil. ;)

mcmwhfy
fonte
Testei novamente seu css e ele funciona no Chrome e um pouco no Firefox, mas não no IE8. (Talvez meu IE8 seja uma versão diferente?) Desde então, eu vim com minha própria solução baseada em js. Veja tahirhassan.blogspot.co.uk/2013/02/…
Tahir Hassan
Jogar um pouco no IE8 com isso e um ajuste posterior ajudou. Eu apenas tive que colocar o pai <td> em uma largura fixa, reposicionar o valor superior e ¡ahí estuvo !. Obrigado
j4v1
2

Um plugin jQuery completo está disponível. Suporta layout ininterrupto e interações com teclado, verifique a página de demonstração: http://powerkiki.github.com/ie_expand_select_width/

isenção de responsabilidade: eu codifiquei aquilo, patches bem-vindos

PowerKiKi
fonte
1

A solução do jquery BalusC foi aprimorada por mim. Também usado: comentário de Brad Robertson aqui .

Basta colocá-lo em um .js, usar a classe ampla para seus combos desejados e não forjar para dar um Id. Chame a função no onload (ou documentReady ou qualquer outro).
Tão simples que :)
Usará a largura que você definiu para o combo como comprimento mínimo.

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');
    })
    }
}
Federico valido
fonte
0

Você pode adicionar um estilo diretamente ao elemento selecionado:

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

Portanto, este item selecionado terá 200 pixels de largura.

Alternativamente, você pode aplicar uma classe ou id ao elemento e referenciá-lo em uma folha de estilo

Katy
fonte
0

Até agora não existe um. Não sei sobre o IE8, mas isso não pode ser feito no IE6 e IE7, a menos que você implemente sua própria funcionalidade de lista suspensa com javascript. Existem exemplos de como fazer isso na web, embora eu não veja muitos benefícios em duplicar a funcionalidade existente.

Pilsetnieks
fonte
0

Temos a mesma coisa em um asp: dropdownlist:

No Firefox (3.0.5), a lista suspensa é a largura do item mais longo da lista suspensa, que tem cerca de 600 pixels de largura ou algo parecido.


fonte
0

Isso parece funcionar com o IE6 e não parece prejudicar os outros. A outra coisa boa é que ele muda o menu automaticamente assim que você muda sua seleção suspensa.

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

});
lhoess
fonte
0

O link Hedgerwow (a solução alternativa para a animação YUI) na primeira melhor resposta está quebrado, acho que o domínio expirou. Copiei o código antes de expirar, então você pode encontrá-lo aqui (o proprietário do código pode me informar se eu estiver violando algum direito autoral, enviando-o novamente)

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

Na mesma postagem do blog, escrevi sobre como fazer exatamente o mesmo elemento SELECT como o normal usando o menu do botão YUI. Dê uma olhada e deixe-me saber se isso ajuda!

Hammad Tariq
fonte
0

Com base na solução postada por Sai , é assim que se faz com 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:''}); });
});
Ahmad Alfy
fonte
0

Pensei em jogar meu chapéu no ringue. Eu faço um aplicativo SaaS e tenho um menu de seleção embutido em uma tabela. Esse método funcionou, mas distorceu tudo na tabela.

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';}"

Então, o que eu fiz para tornar tudo melhor foi colocar o select dentro de uma div indexada por 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>
n0nag0n
fonte
0

É testado em todas as versões do IE, Chrome, FF e Safari

// código JavaScript

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

// Código 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>
Arif
fonte
0

Tentei todas essas soluções e nenhuma funcionou completamente para mim. Isso é o que eu inventei

$(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);

Certifique-se de adicionar uma classe suspensa para cada lista suspensa em seu html

O truque aqui é usar a função de clique especializada (eu a encontrei aqui Fire event cada vez que um item DropDownList é selecionado com jQuery ). Muitas das outras soluções aqui usam a alteração do manipulador de eventos, que funciona bem, mas não será acionada se o usuário selecionar a mesma opção selecionada anteriormente.

Como muitas das outras soluções, o foco e a redução do mouse são para quando o usuário coloca o menu suspenso em foco, o desfoque é para quando ele clica.

Você também pode querer colocar algum tipo de detecção de navegador nisso para que tenha efeitos apenas, ou seja. Mas não parece ruim em outros navegadores

RasTheDestroyer
fonte