Выберите раскрывающийся список с фиксированной шириной обрезки содержимого в IE

Проблема:

Некоторым из выбранных элементов требуется больше, чем указанная ширина 145 пикселей для полного отображения.

Поведение Firefox: при нажатии на выбор открывается раскрывающийся список элементов, настроенный по ширине самого длинного элемента.

Поведение IE6 и IE7: при нажатии на выбор открывается раскрывающийся список элементов, ширина которого ограничена 145 пикселями, что делает невозможным чтение более длинных элементов.

Текущий пользовательский интерфейс требует, чтобы мы поместили это раскрывающееся меню в 145 пикселей и разместили в нем элементы с более длинными описаниями.

Есть какие-нибудь советы по решению проблемы с IE?

Ширина верхнего элемента должна оставаться 145 пикселей даже при расширении списка.

Спасибо!

CSS:

select.center_pull {
    background:#eeeeee none repeat scroll 0 0;
    border:1px solid #7E7E7E;
    color:#333333;
    font-size:12px;
    margin-bottom:4px;
    margin-right:4px;
    margin-top:4px;
    width:145px;
}

Вот выбранный код ввода (в настоящее время нет определения стиля backend_dropbox)

<select id="select_1" class="center_pull backend_dropbox" name="select_1">
<option value="-1" selected="selected">Browse options</option>
<option value="-1">------------------------------------</option>
<option value="224">Option 1</option>
<option value="234">Longer title for option 2</option>
<option value="242">Very long and extensively descriptive title for option 3</option>
</select>

Полная html-страница на случай, если вы хотите быстро протестировать в браузере:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>dropdown test</title>

<style type="text/css">
<!--
select.center_pull {
    background:#eeeeee none repeat scroll 0 0;
    border:1px solid #7E7E7E;
    color:#333333;
    font-size:12px;
    margin-bottom:4px;
    margin-right:4px;
    margin-top:4px;
    width:145px;
}
-->
</style>
</head>

<body>
<p>Select width test</p>
<form id="form1" name="form1" method="post" action="">
<select id="select_1" class="center_pull backend_dropbox" name="select_1">
<option value="-1" selected="selected">Browse options</option>
<option value="-1">------------------------------------</option>
<option value="224">Option 1</option>
<option value="234">Longer title for option 2</option>
<option value="242">Very long and extensively descriptive title for option 3</option>
</select>
</form>
</body>
</html>

person aaandre    schedule 25.03.2009    source источник
comment
На этот вопрос уже был дан ответ ранее в Stack Overflow: stackoverflow.com/questions/73960 / dropdownlist-width-in-ie   -  person Ron DeVera    schedule 25.03.2009
comment
Спасибо, что указали на это. Это решение требует включения массивных библиотек javascript, чего я стараюсь избегать.   -  person aaandre    schedule 26.03.2009
comment
Посмотрите, может ли это то, что вам нужно ... dropdownwidthproblem.blogspot.com   -  person    schedule 23.07.2011


Ответы (23)


Для IE 8 есть простое решение на основе css:

select:focus {
    width: auto;
    position: relative;
}

(Вам необходимо установить свойство position, если поле выбора является дочерним элементом контейнера с фиксированной шириной.)

К сожалению, IE 7 и ниже не поддерживают селектор: focus.

person rusty    schedule 22.12.2010
comment
+1 за указание :focus и width:auto, однако я думаю, что во многих случаях (включая мой) люди захотят использовать position:absolute, и, вероятно, не только для сосредоточения внимания. Если вы не используете position:absolute, дополнительная ширина может привести к выпадению строки из раскрывающегося списка, если он перемещается справа от чего-либо (или встроенного блока). - person Muhd; 09.02.2013

Я обратился в Google по поводу этой проблемы, но не нашел лучшего решения, поэтому создал решение, которое отлично работает во всех браузерах.

просто вызовите функцию badFixSelectBoxDataWidthIE () при загрузке страницы.

function badFixSelectBoxDataWidthIE(){
    if ($.browser.msie){
      $('select').each(function(){
    if($(this).attr('multiple')== false){
      $(this)
          .mousedown(function(){
               if($(this).css("width") != "auto") {
                   var width = $(this).width();
                   $(this).data("origWidth", $(this).css("width"))
                          .css("width", "auto");
                   /* if the width is now less than before then undo */
                   if($(this).width() < width) {
        $(this).unbind('mousedown');
                       $(this).css("width", $(this).data("origWidth"));
                   }
               }
           })
           /* Handle blur if the user does not change the value */
           .blur(function(){
               $(this).css("width", $(this).data("origWidth"));

           })
           /* Handle change of the user does change the value */
           .change(function(){
               $(this).css("width", $(this).data("origWidth"));

           });
        }
      });
    }
    }
person Community    schedule 30.12.2010
comment
это хорошо, но оно расширяет фактический элемент управления выбором, который сдвигает все вправо - person DaveDev; 09.03.2011
comment
Как упоминал DaveDev, это может быть проблемой, если у вас особый дизайн, но в остальном это полезно и легко реализовать, спасибо за код! - person Mauro Morales; 04.04.2011
comment
Он расширяет фактический элемент управления выбором только тогда, когда я нажимаю на них. Я заполняю эти элементы управления выбором с помощью ajax. В настоящее время я вызываю его в функции $ (document) .ready ()! Я делаю что-то неправильно? - person zer0c00l; 20.09.2011
comment
Привет, zer0c00l, да Вы пропустили одну часть привязки событий. Вам также необходимо вызвать эту функцию при успешном использовании ajax после вставки элементов в элемент DOM. - person Anoop Sharma; 31.01.2013
comment
да, вы пропустили одну небольшую проблему с привязкой. Вы должны вызвать ту же функцию в Ajax success также после вставки чего-либо в элемент DOM. Дополнительные разъяснения можно найти в блоге. anoopkumarsharma.com/ - person Anoop Sharma; 31.01.2013
comment
@ user558204 Всякий раз, когда ссылаетесь на ваш собственный сайт, вы должны сообщать, что это ваш сайт. Я знаю, что это ваш, потому что вы только что разместили этот код в своем блоге, а теперь внезапно продвигаете его здесь. - person Andrew Barber; 31.01.2013
comment
Пожалуйста, не используйте подписи / слоганы в своих сообщениях. Ваш ящик пользователя считается вашей подписью, и вы можете использовать свой профиль для публикации любой информации о себе, которая вам нравится. Часто задаваемые вопросы о подписях / слоганах - person Andrew Barber; 12.02.2013
comment
@ Андрей Спасибо. обязательно в будущем. - person Anoop Sharma; 12.02.2013

Вот небольшой сценарий, который должен вам помочь:

http://www.icant.co.uk/forreview/tamingselect/

person Zac    schedule 25.03.2009
comment
Спасибо. Мне интересно, знает ли кто-нибудь о решении без javascript? - person aaandre; 26.03.2009
comment
я нашел это решение намного лучше (вам не нужно менять свой код): css-tricks.com/select-cuts-off-options-in-ie-fix - person tuffo19; 12.06.2013

Для простого решения без Javascript добавления атрибута title к вашим ‹option›, содержащим текст, может быть достаточно, в зависимости от ваших требований.

<option value="242" title="Very long and extensively descriptive text">
  Very long and extensively descriptive text
</option>

Это покажет обрезанный текст в виде всплывающей подсказки при наведении курсора на ‹option›, независимо от ширины ‹select›.

Работает с IE7 +.

person islander    schedule 10.02.2011

Боюсь, что не без javascript, но мне удалось сделать его совсем маленьким с помощью jQuery.

$('#del_select').mouseenter(function () {

    $(this).css("width","auto");

});

$('#del_select').mouseout(function () {

    $(this).css("width","170px");

}); 
person stukerr    schedule 17.07.2009
comment
Мне понравился ваш подход KISS, но попытка выбрать вызовет наведение мыши. Попробуйте следующее: $ .fn.ie_select_expando = function () {if (! $. Browser.msie) return; var s = $ (this); s.data ('o', false); s.mouseenter (function () {если (! s.data ('owidth')) s.data ('owidth', s.css ('width')); s.css (width, auto);}). mouseout (function () {if (! s.data ('o')) s.css (width, s.data ('owidth'));}). blur (function () {if (s.data ('o')) {s. css (width, s.data ('owidth')); s.data ('o', false);}}). click (function () {if (s.data ('o')) {s.css (ширина, s.data ('owidth')); s.data ('o', false);} else {s.css (width, auto); s.data ('o', true);}}) ;} - person ynkr; 09.12.2010

Просто вы можете использовать этот плагин для jquery;)

http://plugins.jquery.com/project/skinner

$(function(){
          $('.select1').skinner({'width':'200px'});
});
person anbi    schedule 06.10.2011

Небольшое, но, надеюсь, полезное обновление кода от MainMa и user558204 (спасибо, ребята), которое удаляет ненужный каждый цикл, сохраняет копию $ (this) в переменной в каждом обработчике событий, поскольку он используется более одного раза, а также объединяет размытие и изменение событий, поскольку они имеют одно и то же действие.

Да, он все еще не идеален, поскольку изменяет размер элемента выбора, а не только раскрывающихся параметров. Но послушайте, это меня вывело из затруднительного положения, мне (очень, очень, к сожалению) все еще нужно поддерживать доминирующую базу пользователей IE6 во всем бизнесе.

// IE test from from: https://gist.github.com/527683
var ie = (function () {
  var undef, v = 3, div = document.createElement('div'), all = div.getElementsByTagName('i');
  while (
    div.innerHTML = '<!--[if gt IE ' + (++v) + ']><i></i><![endif]-->',
    all[0]
  );
  return v > 4 ? v : undef;
} ());


function badFixSelectBoxDataWidthIE() {
  if (ie < 9) {
    $('select').not('[multiple]')
      .mousedown(function() {
        var t = $(this);
        if (t.css("width") != "auto") {
          var width = t.width();
          t.data("ow", t.css("width")).css("width", "auto");

          // If the width is now less than before then undo
          if (t.width() < width) {
            t.unbind('mousedown');
            t.css("width", t.data("ow"));
          }
        }
      })

      //blur or change if the user does change the value
      .bind('blur change', function() {
        var t = $(this);
        t.css("width", t.data("ow"));
      });
  }
}
person TechSpud    schedule 01.05.2012

Другой подход:

  1. вместо выбора сделайте его полем редактирования, отключенным, чтобы никто не мог вводить что-либо вручную или изменять содержимое после выбора
  2. другое скрытое редактирование, содержащее идентификатор выбранной опции (объяснено ниже)
  3. сделайте кнопку [..] и напишите сценарий, чтобы показать этот div ниже
  4. создать скрытый div с абсолютной позицией под или рядом с полем редактирования
  5. сделайте этот div, чтобы он содержал выбор со стилем size = "6" (чтобы показать 6 вариантов и полосу прокрутки, а не раскрывающийся список) и кнопку "выбрать" и, возможно, "отменить"
  6. Не стилизуйте ширину, поэтому все будет принимать ширину самого широкого варианта или кнопки плюс, возможно, некоторые отступы по вашему выбору.
  7. скрипт кнопки «выбрать», чтобы скопировать идентификатор выбранной опции в скрытое поле редактирования и его значение в видимое, а также снова скрыть div.

Всего 4 простые команды javascript.

person Kitet    schedule 30.09.2010

Я нашел довольно простое решение для этого. В элементе <select> html добавьте следующие свойства:

onmouseover="autoWidth(this)" 
onblur="resetWidth(this)" 

Таким образом, всякий раз, когда пользователь нажимает на эту ширину, она автоматически расширяется и пользователь выходит из поля выбора, ширина будет сброшена на исходную.

person TheOnlyOne    schedule 14.05.2010

аналогичное решение можно найти здесь, используя jquery для установки автоматической ширины при фокусе (или mouseenter) и возврата исходной ширины при размытии (или mouseleave) http://css-tricks.com/select-cuts-off-options-in-ie-fix/.

person schrodinger's code    schedule 21.02.2011

for (i=1;i<=5;i++){
   idname = "Usert" + i;
   document.getElementById(idname).style.width = "100%";

}

Я использовал этот способ, чтобы показать раскрывающийся список, когда ширина отображается неправильно.

Он работает для IE6, Firefox и Chrome.

person keong    schedule 04.05.2011

Доступен полноценный плагин jQuery, посмотрите демонстрационную страницу: http://powerkiki.github.com/ie_expand_select_width/

отказ от ответственности: я закодировал эту вещь, патчи приветствуются

person PowerKiKi    schedule 20.08.2012
comment
Это было проверено на IE7? Вот где у меня проблема - у моего клиента, похоже, есть только люди, которые никогда не обновляли свой браузер, поэтому они используют IE7 или всегда обновляются, поэтому они используют IE9 (или Firefox). У людей, которые всегда обновляются, нет проблем. - person Paul Tomblin; 07.09.2012
comment
Как указано на домашней странице, это только IE8. Никогда не тестировал в IE7. И извините за поздний ответ: - / - person PowerKiKi; 12.02.2013

Зачем кому-то нужно навести указатель мыши на событие в раскрывающемся списке? Вот способ управления IE8 таким образом, чтобы раскрывающийся список работал:

Во-первых, давайте убедимся, что мы передаем нашу функцию только в IE8:

    var isIE8 = $.browser.version.substring(0, 2) === "8.";
    if (isIE8) {
       //fix me code
    }

Затем, чтобы позволить выделению расширяться за пределы области содержимого, давайте обернем наши раскрывающиеся списки в div с правильной структурой, если это еще не сделано, а затем вызовем вспомогательную функцию:

        var isIE8 = $.browser.version.substring(0, 2) === "8.";
    if (isIE8) {
        $('select').wrap('<div class="wrapper" style="position:relative; display: inline-block; float: left;"></div>').css('position', 'absolute');

        //helper function for fix
        ddlFix();
    }

Теперь о событиях. Поскольку IE8 генерирует событие после фокусировки по какой-либо причине, IE закроет виджет после рендеринга при попытке расширения. Обходной путь будет заключаться в привязке к классам 'focusin' и 'focusout', которые будут автоматически расширяться на основе самого длинного текста параметра. Затем, чтобы обеспечить постоянную минимальную ширину, которая не сжимается выше значения по умолчанию, мы можем получить текущую ширину списка выбора и установить ее для свойства минимальной ширины раскрывающегося списка в 'onchange' привязка:

    function ddlFix() {
    var minWidth;

    $('select')

    .each(function () {
        minWidth = $(this).width();
        $(this).css('min-width', minWidth);
    })
    .bind('focusin', function () {
        $(this).addClass('expand');
    })
    .change(function () {
        $(this).css('width', minWidth);
    })
    .bind('focusout', function () {
        $(this).removeClass('expand');
    });
}

Наконец, не забудьте добавить этот класс в таблицу стилей:

 select:focus, select.expand {
    width: auto;
}
person Ben Sewards    schedule 20.09.2012

Не без javascript, я тоже боюсь, и для моего решения требуется библиотека js, однако вы можете использовать только те файлы, которые вам нужны, а не использовать их все, возможно, лучше всего подходят для тех, кто уже использует YUI для своих проектов или решает, какие один для использования. Взгляните на: http://ciitronian.com/blog/programming/yui-button-mimicking-native-select-dropdown-avoid-width-problem/

В моем сообщении в блоге также обсуждаются другие решения, одно из которых упоминается здесь, в stackoverflow, почему я вернулся, чтобы создать свой собственный элемент SELECT, по простой причине, мне не нравятся события развертывания при наведении курсора мыши. Может быть, если это поможет кому-то еще!

person Hammad Tariq    schedule 02.07.2010

Решение jquery BalusC улучшено мной. Также используется: здесь.

Просто поместите это в .js, используйте широкий класс для желаемых комбинаций и не пытайтесь присвоить ему идентификатор. Вызовите функцию в onload (или documentReady или что-то еще).
Как простая задница :)
Она будет использовать ширину, которую вы определили для комбо, как минимальную длину.

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');
    })
    }
}
person Federico Valido    schedule 05.09.2011

Он протестирован во всех версиях IE, Chrome, FF и Safari.

// Код JavaScript

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

// Html code

    <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>
person Arif    schedule 08.05.2012

У меня есть еще один вклад в это. Я написал это некоторое время назад, и это может вам помочь: http://dpatrickcaldwell.blogspot.com/2011/06/giantdropdown-jquery-plugin-for-styling.html

Это плагин jquery для создания неупорядоченного списка со стилем, поддерживаемого скрытым элементом выбора.

Источник находится на github: https://github.com/tncbbthositg/GiantDropdown

Вы сможете обрабатывать поведение и стили в UL, чего не можете сделать с помощью SELECT. Все остальное должно быть таким же, потому что список выбора все еще существует, он просто скрыт, но UL будет использовать его в качестве резервного хранилища данных (если хотите).

person D. Patrick    schedule 26.06.2012

Я хотел, чтобы это работало с выбранными элементами, которые я динамически добавлял на страницу, поэтому после множества экспериментов я закончил тем, что предоставил все выбранные элементы, которые я хотел сделать, с помощью класса «fixedwidth», а затем добавил следующий CSS:

table#System_table select.fixedwidth { width: 10em; }
table#System_table select.fixedwidth.clicked { width: auto; }

и этот код

<!--[if lt IE 9]>
    <script type="text/javascript">
        jQuery(document).ready(function() {
            jQuery(document).on(
              {
                'mouseenter': function(event) {
                    jQuery(this).addClass('clicked');
                    },
                'focusout change blur': function() {
                    jQuery(this).removeClass('clicked');
                    }
              }, 'select.fixedwidth');
        });
    </script>
<![endif]-->

Несколько замечаний:

  • Несмотря на то, что все мои выборки находятся в таблице, мне пришлось сделать «on» для jQuery(document).on, а не для jQuery('table#System_table').on
  • Несмотря на то, что в документации jQuery говорится об использовании «mouseleave» вместо «blur», я обнаружил, что в IE7, когда я перемещал мышь вниз по раскрывающемуся списку, он получал событие mouseleave, но не blur.
person Paul Tomblin    schedule 08.09.2012

Вот решение, которое действительно работает.

Он устанавливает ширину в IE и не портит макет страницы и не закрывает раскрывающийся список при наведении указателя мыши на параметры выбора, как некоторые другие решения на этой странице.

Однако вам нужно будет изменить значение margin-right и значения ширины, чтобы они соответствовали тому, что у вас есть для выбранных полей.

Также вы можете заменить $('select') на $('#Your_Select_ID_HERE'), чтобы воздействовать только на определенное поле выбора. Также вам нужно будет вызвать функцию fixIESelect() в теле onload или через jQuery, используя DOM ready, как я сделал в моем коде ниже:

//////////////////////////
// FIX IE SELECT INPUT //
/////////////////////////
window.fixIESelect_clickset = false;
function fixIESelect()
{
 if ($.browser.msie)
 {
  $('select').mouseenter(function ()
  {
   $(this).css("width","auto");
   $(this).css("margin-right","-100");
  });
  $('select').bind('click focus',function ()
  {
   window.fixIESelect_clickset = true;
  });
  $('select').mouseout(function ()
  {
   if(window.fixIESelect_clickset != true)
   {
    $(this).css("width","93px");
    window.fixIESelect_clickset = false;
   }
  });
  $('select').bind('blur change',function ()
  {
   $(this).css("width","93px");
  });
 }
}
/////////////
// ONLOAD //
////////////
$(document).ready(function()
{
 fixIESelect();
});
person Gallagher    schedule 19.07.2012

Для моего макета я не хотел взлома (без увеличения ширины, без щелчка с авто, а затем возврата к исходному). Это нарушило мой существующий макет. Я просто хотел, чтобы он работал нормально, как и другие браузеры.

Я обнаружил, что это именно так: -

http://www.jquerybyexample.net/2012/05/fix-for-ie-select-dropdown-with-fixed.html

person Steve    schedule 10.01.2015

Обходной путь, если вас не волнует странный вид после выбора опции (например, выберите, чтобы перейти на новую страницу):

<!-- Limit width of the wrapping div instead of the select and use 'overflow: hidden' to hide the right part of it. -->
<div style='width: 145px; overflow: hidden; border-right: 1px solid #aaa;'>
  <select onchange='jump();'>
    <!-- '&#9660;(▼)' produces a fake dropdown indicator -->
    <option value=''>Jump to ... &#9660;</option>
    <option value='1'>http://stackoverflow.com/questions/682764/select-dropdown-with-fixed-width-cutting-off-content-in-ie</option>
    ...
  </select>
</div>
person Mergen Wu    schedule 26.06.2015

Чистое решение css: http://bavotasan.com/2011/style-select-box-using-only-css/

.styled-select select {
   background: transparent;
   width: 268px;
   padding: 5px;
   font-size: 16px;
   line-height: 1;
   border: 0;
   border-radius: 0;
   height: 34px;
   -webkit-appearance: none;
   }

.styled-select {
   width: 240px;
   height: 34px;
   overflow: hidden;
   background: url(http://cdn.bavotasan.com/wp-content/uploads/2011/05/down_arrow_select.jpg) no-repeat right #ddd;
   border: 1px solid #ccc;
   }
<div class="styled-select">
   <select>
      <option>Here is the first option</option>
      <option>The second option</option>
   </select>
</div>

person Teenage    schedule 07.08.2015

Лучшее решение: css + javascript

http://css-tricks.com/select-cuts-off-options-in-ie-fix/

var el;

$("select")
  .each(function() {
    el = $(this);
    el.data("origWidth", el.outerWidth()) // IE 8 can haz padding
  })
  .mouseenter(function(){
    $(this).css("width", "auto");
  })
  .bind("blur change", function(){
    el = $(this);
    el.css("width", el.data("origWidth"));
  });
person tuffo19    schedule 12.06.2013