Выберите раскрывающийся список с фиксированной шириной отсечения содержимого в 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"));
});
}
});
}
}
для простого решения без 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"));
});
}
}
другой подход:
- вместо выбора сделайте его полем редактирования, отключенным, чтобы никто не мог ввести что-либо вручную или изменить содержимое после выбора
- другое скрытое редактирование, содержащее идентификатор выбранного параметра (описано ниже)
- создать кнопку [..] и сценарий его, чтобы показать, что div ниже
- сделать скрытый div с абсолютной позицией, под или рядом с поле
- сделайте, чтобы div содержал выбор с размером стиля= " 6" (чтобы показать 6 опций и полосу прокрутки, а не раскрывающийся список) и кнопку "Выбрать" и, возможно, "отменить"
- не стилизуйте ширину, чтобы все это предполагало ширину самого широкого варианта или кнопки плюс, возможно, некоторую прокладку по вашему выбору
- 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();'>
<!-- '▼(▼)' produces a fake dropdown indicator -->
<option value=''>Jump to ... ▼</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"));
});