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


вопрос:

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

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

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 55

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 бросает событие после фокусировки по какой-либо причине, т. е. закроет виджет после рендеринга при попытке развернуть. Работа вокруг будет привязываться к '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 expand events. Может быть, если это поможет кому-то еще тоже!

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 будет использовать его в качестве резервного хранилища данных (если хотите).

Я хотел, чтобы это работало с выборками, которые я добавил динамически на страницу, поэтому после многих экспериментов я в конечном итоге дал все выборки, которые я хотел сделать с классом "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]-->

несколько вещей, чтобы отметить:

  • несмотря на то, что мои выбирает все в таблице, я должен был сделать "на" к jQuery(document).on вместо to jQuery('table#System_table').on
  • In несмотря на то, что документация jQuery говорит использовать "mouseleave" вместо "blur", я обнаружил, что в IE7, когда я переместил мышь вниз по выпадающему списку, он получит mouseleave событие, а не blur.

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

он устанавливает ширину в 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();
});

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

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

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