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

вопрос:

некоторые из элементов в select требуют больше, чем заданная ширина 145px для полного отображения.

поведение в Firefox: щелчок по select показывает выпадающий список элементов, настроенный на ширину самого длинного элемента.

в IE6 & IE7 и поведение: щелчок по select показывает выпадающий список элементов, ограниченный шириной 145px, что делает невозможным чтение дольше элементы.

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

любые советы по решению проблемы с IE?

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

спасибо!

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>

23 ответов


для IE 8 существует простое решение на основе css:

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

(необходимо задать свойство position, если selectbox является дочерним для контейнера с фиксированной шириной.)

к сожалению IE 7 и менее не поддерживают :Focus selector.


Я сделал 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"));

           });
        }
      });
    }
    }

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

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


для простого решения без Javascript достаточно добавить атрибут title к вашему

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

при наведении курсора на

работает для IE7+.


Не javascript бесплатно, я боюсь, но мне удалось сделать его довольно маленьким, используя jQuery

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

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

});

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

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

}); 

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

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

$(function(){
          $('.select1').skinner({'width':'200px'});
});

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

Да, он все еще не идеален, поскольку он изменяет размер элемента select, а не только раскрывающиеся параметры. Но эй, это вытащило меня из неприятностей, я (очень, очень к сожалению) все еще должен поддержка 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"));
      });
  }
}

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

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

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


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

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

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


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


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

}

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

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


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

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


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

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

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

затем, чтобы разрешить select расширяться за пределами области содержимого, давайте обернем наши выпадающие списки в 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();
    }

теперь о событиях. С ИЕ8 бросает событие после фокусировки по какой-либо причине, IE закроет виджет после рендеринга при попытке развернуть. Работа вокруг будет привязываться к 'focusin' и 'focusout' класс, который будет автоматически расширяться на основе самого длинного текста опции. Затем, чтобы обеспечить постоянную минимальную ширину, которая не сжимается после значения по умолчанию, мы можем получить текущую ширину списка выбора и установить ее в раскрывающемся списке min-width свойство '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;
}

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

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


в jQuery BalusC это решение улучшено мной. Используются также: комментарий.

просто поместите это в a .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');
    })
    }
}

его тестирование во всех версиях 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>

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

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

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

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


Я хотел, чтобы это работало с selects, которые я добавил динамически на страницу, поэтому после многих экспериментов я в конечном итоге дал все варианты, которые я хотел сделать с классом "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
  • In несмотря на то, что в документации jQuery говорится использовать "mouseleave" вместо "blur", я обнаружил, что в IE7, когда я переместил мышь вниз по выпадающему списку, она получит mouseleave событие, а не blur.

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

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

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

также вы можете заменить $('select') С $('#Your_Select_ID_HERE') для действия только определенного поля select. Как и ты нужно будет вызвать функцию 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();
});

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

Я нашел, что это именно так:

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


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

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

чистое решение 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>

лучшее решение: 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"));
  });