Largura da lista suspensa no IE
-
09-06-2019 - |
Pergunta
No IE, a lista suspensa tem a mesma largura da caixa de depósito (espero estar fazendo sentido), enquanto no Firefox a largura da lista suspensa varia de acordo com o conteúdo.
Basicamente, isso significa que preciso garantir que a caixa de depósito seja larga o suficiente para exibir a seleção mais longa possível.Isso faz minha página parecer 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?
Solução
Aqui está outro jQuery exemplo baseado.Ao contrário de todas as outras respostas postadas aqui, leva em consideração todos os eventos de teclado e mouse, especialmente 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 que você precisa fazer é adicionar a classe wide
para o(s) elemento(s) suspenso(s) em questão.
<select class="wide">
...
</select>
Aqui está um exemplo jsfiddle.Espero que isto ajude.
Outras dicas
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 caixas de seleção do IE.
Você precisará incluir o seguinte e embrulhar seu <select>
elementos em um <span class="select-box">
Coloque-os antes da tag body 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 pós-aceitação:
Você também pode fazer isso sem a biblioteca YUI e o controle 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 bela 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 (ele não considera o mouseover nas opções como um mouseover na seleção).Isso torna o uso do mouseout muito complicado.A primeira solução é a melhor que encontrei até agora.
você poderia simplesmente 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 funciona para mim.Nada mais é necessário.
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>
Observação:o $.navegador.msie requer jquery.
@Thad, você também precisa adicionar um manipulador de eventos de desfoque
$(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)
Não há como fazer isso no IE6/IE7/IE8.O controle é desenhado pelo aplicativo e o IE simplesmente não o desenha dessa forma.Sua melhor aposta é implementar seu próprio menu suspenso por meio de HTML/CSS/JavaScript simples, se for tão importante ter o menu suspenso com uma largura e a lista com outra largura.
Se você usa jQuery, experimente este plugin de seleção de largura 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 em 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.
No jQuery isso funciona bastante bem.Suponha que o menu suspenso tenha 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");
}
});
});
Aqui está a solução mais simples.
Antes de começar, devo dizer que a caixa de seleção suspensa será expandida automaticamente em quase todos os navegadores, exceto o IE6.Então, eu faria uma verificação do navegador (ou seja, IE6) e escreveria o seguinte apenas para esse navegador.Aqui vai.Primeiro verifique o navegador.
O código expandirá magicamente a caixa de seleção suspensa.O único problema com a solução é que ao passar o mouse sobre 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 no 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 você mesmo o código abaixo e use-o se quiser.
.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 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.--%>
}
se você quiser um menu suspenso e/ou flutuante simples, sem efeitos de transição, basta usar CSS ...você pode forçar o IE6 a suportar :hover em todos os elementos usando um arquivo .htc (css3hover?) Com comportamento (propriedade somente do IE6) definido no arquivo CSS anexado condicionalmente.
Veja isso..não é perfeito, mas funciona e é apenas para o IE e não afeta o FF.Usei o javascript regular para onmousedown para estabelecer apenas a correção do IE.mas o msie do jquery também pode ser usado no onmousedown.a idéia principal é "onchange" e on blur para que a caixa de seleção volte ao normal...decida sua própria largura para eles.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%'"
A resposta do BalusC acima funciona muito bem, mas há uma pequena correção que eu acrescentaria se o conteúdo do seu menu suspenso tiver uma largura menor do que a que você define no seu CSS select.expand, adicione isto ao link do mouse:
.bind('mouseover', function() { $(this).addClass('expand').removeClass('clicked');
if ($(this).width() < 300) // put your desired minwidth here
{
$(this).removeClass('expand');
}})
Isso é algo que fiz pegando pedaços de 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 texto de opção mais largo que a largura da própria seleção.
Como você pode ver, especifiquei document.all porque isso só funciona no IE.Além disso, coloquei 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 cuida dos outros elementos que saem do lugar quando o menu suspenso se expande.A única desvantagem aqui é que o visual da lista de menus desaparece quando você seleciona, mas retorna assim que você seleciona.
Espero que isso ajude alguém.
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ó que isso é mais fácil.;)
Um plugin jQuery completo está disponível.Ele suporta layout ininterrupto e interações de teclado, confira a página de demonstração: http://powerkiki.github.com/ie_expand_select_width/
isenção de responsabilidade:Eu codifiquei aquela coisa, patches são bem-vindos
A solução jquery BalusC melhorada por mim.Usado também:Brad Robertson comente aqui.
Basta colocar isso em um .js, usar a classe ampla para os combos desejados e não forjar um ID.Chame a função no onload (ou documentReady ou qualquer outro).
Tão simples assim :)
Ele 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');
})
}
}
Você pode adicionar um estilo diretamente ao elemento select:
<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
Até agora não há nenhum.Não sei sobre o IE8, mas isso não pode ser feito no IE6 e no 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 funcionalidades existentes.
Temos a mesma coisa em um asp:dropdownlist:
No Firefox (3.0.5), o menu suspenso é a largura do item mais longo no menu suspenso, que tem cerca de 600 pixels de largura ou algo parecido.
Isso parece funcionar com o IE6 e não parece prejudicar outros.A outra coisa interessante é que ele muda o menu automaticamente assim que você altera a 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");
}
});
});
O link hedgerwow (a solução alternativa da animação YUI) na primeira melhor resposta está quebrado, acho que o domínio expirou.Copiei o código antes de ele expirar, então você pode encontrá-lo aqui (o proprietário do código pode me informar se estou violando algum direito autoral, enviando-o novamente)
Na mesma postagem do blog, escrevi sobre como criar exatamente o mesmo elemento SELECT como o normal usando o menu do botão YUI.Dê uma olhada e me diga se isso ajuda!
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:''}); });
});
Pensei em jogar meu chapéu no ringue.Eu faço um aplicativo SaaS e tinha um menu de seleção incorporado 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 fiz para melhorar tudo foi colocar o select dentro de uma div indexada em 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>
É 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>
Tive que contornar esse problema e uma vez encontrei uma solução bastante completa e escalonável, funcionando para IE6, 7 e 8 (e compatível com outros navegadores, obviamente).Escrevi um artigo inteiro sobre isso aqui: http://www.edgeoftheworld.fr/wp/work/dealing-with-fixed-sized-dropdown-lists-in-internet-explorer
Pensei em compartilhar isso com as pessoas que ainda enfrentam esse problema, pois nenhuma das soluções acima funciona em todos os casos (na minha opinião).
Tentei todas essas soluções e nenhuma funcionou completamente para mim.Isto é 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 a cada lista suspensa em seu html
O truque aqui é usar a função de clique especializada (encontrei aqui Evento de disparo 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 outras soluções, o foco e o mouse são para quando o usuário coloca o menu suspenso em foco, o desfoque é para quando ele clica fora.
Você também pode querer colocar algum tipo de detecção de navegador para que isso afete apenas, ou seja.Não parece ruim em outros navegadores