简体   繁体   English

选择固定宽度的下拉列表切断IE中的内容

[英]Select dropdown with fixed width cutting off content in IE

The issue: 问题:

Some of the items in the select require more than the specified width of 145px in order to display fully. select中的某些项目需要超过145px的指定宽度才能完全显示。

Firefox behavior : clicking on the select reveals the dropdown elements list adjusted to the width of the longest element. Firefox行为 :单击选择会显示调整为最长元素宽度的下拉元素列表。

IE6 & IE7 behavior : clicking on the select reveals the dropdown elements list restricted to 145px width making it impossible to read the longer elements. IE6和IE7行为 :单击选择会显示下拉元素列表限制为145px宽度,因此无法读取更长的元素。

The current UI requires us to fit this dropdown in 145px and have it host items with longer descriptions. 当前的UI要求我们在145px中放入此下拉列表,并让它包含更长描述的项目。

Any advise on resolving the issue with IE? 有关解决IE问题的任何建议吗?

The top element should remain 145px wide even when the list is expanded. 即使扩展列表,顶部元素仍应保持145px宽。

Thank you! 谢谢!

The css: 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;
}

Here's the select input code (there's no definition for the backend_dropbox style at this time) 这是选择输入代码(此时没有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>

Full html page in case you want to quickly test in a browser: 完整的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>

For IE 8 there is a simple pure css-based solution: 对于IE 8,有一个简单的纯css解决方案:

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

(You need to set the position property, if the selectbox is child of a container with fixed width.) (如果selectbox是具有固定宽度的容器的子项,则需要设置position属性。)

Unfortunately IE 7 and less do not support the :focus selector. 不幸的是IE 7及更少不支持:焦点选择器。

I did Google about this issue but didn't find any best solution ,So Created a solution that works fine in all browsers. 关于这个问题我做了Google,但没有找到任何最佳解决方案,所以创建了一个适用于所有浏览器的解决方案。

just call badFixSelectBoxDataWidthIE() function on page load. 只需在页面加载时调用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"));

           });
        }
      });
    }
    }

For a simple Javascript-free solution, adding a title-attribute to your <option>s holding the text might be enough, depending on your requirements. 对于一个简单的无Javascript解决方案,根据您的要求,为您的<option>添加title属性可能就足够了。

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

This will show the cut-off text in a tool-tip fashion on hovering the <option>, regardless of the width of the <select>. 无论<select>的宽度如何,这都将在悬停<option>时以工具提示的方式显示截止文本。

Works for IE7+. 适用于IE7 +。

Here is a little script that should help you out: 这是一个应该帮助你的小脚本:

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

Not javascript free i'm afraid, but I managed to make it quite small using jQuery 不是javascript免费我害怕,但我设法使用jQuery使其非常小

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

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

});

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

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

}); 

Simply you can use this plugin for jquery ;) 只需将此插件用于jquery;)

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

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

Small, but hopefully useful update to the code from MainMa & user558204 (thanks guys), which removes the unnecessary each loop, stores a copy of $(this) in a variable in each event handler as it's used more than once, also combined the blur & change events as they had the same action. 对MainMa和us​​er558204(感谢大家)的代码进行小的,但希望有用的更新,删除不必要的每个循环,将$(this)的副本存储在每个事件处理程序的变量中,因为它不止一次使用,也结合了模糊和更改事件,因为他们有相同的动作。

Yes, it's still not perfect as it resizes the select element, rather than just the drop-down options. 是的,它仍然不完美,因为它调整了select元素的大小,而不仅仅是下拉选项。 But hey, it got me out of a pickle, I (very, very unfortunately) still have to support an IE6-dominant user base across the business. 但是,嘿,它让我脱离了泡沫,我(非常,非常不幸)仍然需要支持整个企业的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"));
      });
  }
}

A full fledged jQuery plugin is available, check out the demo page: http://powerkiki.github.com/ie_expand_select_width/ 有一个完整的jQuery插件可用,请查看演示页面: http//powerkiki.github.com/ie_expand_select_width/

disclaimer: I coded that thing, patches welcome 免责声明:我编写了那个东西,欢迎补丁

Why would anyone want a mouse over event on a drop down list? 为什么有人想在下拉列表中使用鼠标悬停事件? Here's a way of manipulating IE8 for the way a drop down list should work: 这是一种操作IE8的方法,用于下拉列表的工作方式:

First, let's make sure we are only passing our function in IE8: 首先,让我们确保我们只在IE8中传递我们的函数:

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

Then, to allow the select to expand outside of the content area, let's wrap our drop down lists in div's with the correct structure, if not already, and then call the helper function: 然后,为了允许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();
    }

Now onto the events. 现在进入活动。 Since IE8 throws an event after focusing in for whatever reason, IE will close the widget after rendering when trying to expand. 由于IE8因为任何原因而在聚焦后抛出一个事件,因此在尝试扩展时,IE将在渲染后关闭窗口小部件。 The work around will be to bind to 'focusin' and 'focusout' a class that will auto expand based on the longest option text. 解决方法是绑定到'focusin''focusout'这个类,它将根据最长的选项文本自动扩展。 Then, to ensure a constant min-width that doesn't shrink past the default value, we can obtain the current select list width, and set it to the drop down list min-width property on the 'onchange' binding: 然后,为了确保不缩小超过默认值的恒定最小宽度,我们可以获得当前选择列表宽度,并将其设置为'onchange'绑定上的下拉列表min-width属性:

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

Lastly, make sure to add this class in the style sheet: 最后,确保在样式表中添加此类:

 select:focus, select.expand {
    width: auto;
}

I found a pretty straightforward fix for this. 我找到了一个非常直接的解决方案。 In the <select> html element add these properties: <select> html元素中添加以下属性:

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

So whenever user clicks on that the width will automatically expand, and user moves out of the select box, the width will be reset to original. 因此,每当用户点击时,宽度将自动展开,并且用户移出选择框,宽度将重置为原始宽度。

A different approach: 一种不同的方法:

  1. instead of a select make it an edit box, disabled so noone can enter anything manually or change contents after selection 而不是选择使其成为编辑框,禁用,以便没有人可以手动输入任何内容或在选择后更改内容
  2. another hidden edit to contain an id of a selected option (explained below) 另一个隐藏的编辑,包含所选选项的ID(如下所述)
  3. make a button [..] and script it to show that div below 制作一个按钮[..]并编写脚本以显示下面的div
  4. make a hidden div with absolute position under or near the edit box 在编辑框下方或附近创建一个具有绝对位置的隐藏div
  5. make that div to contain a select with style size="6" (to show 6 options and a scrollbar rather than a drop-down list) and a button "select" and maybe "cancel" 使该div包含样式大小=“6”的选择(显示6个选项和滚动条而不是下拉列表)和按钮“选择”并可能“取消”
  6. Do not style width so the whole thing will assume width of the widest option or the button plus maybe some padding of your choice 不要设置宽度,所以整个事物将假设最宽的选项或按钮的宽度加上你选择的一些填充
  7. script the "select" button to copy id of the selected option to the hidden edit box and it's value to the visible one, also to hide the div again. 脚本“选择”按钮将所选选项的ID复制到隐藏的编辑框,并将其值显示为可见的选项,同时再次隐藏div。

4 simple javascript commands total. 共有4个简单的javascript命令。

类似的解决方案可以在这里使用jquery设置焦点(或鼠标中心)时的自动宽度,并在模糊(或鼠标离开)时设置原始宽度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%";

}

I used this way to showed the drop down list when the width is not showed correctly. 当宽度未正确显示时,我用这种方式显示下拉列表。

It work for IE6, Firefox and Chrome. 它适用于IE6,Firefox和Chrome。

Its tested in all version of IE, Chrome, FF & Safari 它在所有版本的IE,Chrome,FF和Safari中进行了测试

// JavaScript code // 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>

I've got yet another contribution to this. 我还有另外一个贡献。 I wrote this a while back that you may find helpful: http://dpatrickcaldwell.blogspot.com/2011/06/giantdropdown-jquery-plugin-for-styling.html 我写了一段时间,你可能会觉得有用: http//dpatrickcaldwell.blogspot.com/2011/06/giantdropdown-jquery-plugin-for-styling.html

It's a jquery plugin to make a styleable unordered list backed by the hidden select element. 这是一个jquery插件,可以创建一个由隐藏的select元素支持的可样式无序列表。

The source is on github: https://github.com/tncbbthositg/GiantDropdown 源代码在github上: https//github.com/tncbbthositg/GiantDropdown

You'd be able to handle behaviors and styles on the UL that you can't with the SELECT. 您将能够处理UL上无法使用SELECT的行为和样式。 Everything else should be the same because the select list is still there, it's just hidden but the UL will use it as a backing data store (if you will). 其他所有内容应该是相同的,因为选择列表仍然存在,它只是隐藏但UL将其用作后备数据存储(如果您愿意)。

Here is a solution that actually works. 这是一个实际有效的解决方案。

It sets the width in IE and doesn't mess up your page layout and doesn't close the dropdown when you mouse over the select options like some of the other solutions on this page. 它在IE中设置宽度并且不会弄乱您的页面布局,并且当您将鼠标悬停在此页面上的某些其他解决方案之类的选项上时不会关闭下拉列表。

You will need however to change the margin-right value and width values to match what you have for your select fields. 但是,您需要更改margin-right值和宽度值,以匹配您对选择字段的值。

Also you can replace the $('select') with $('#Your_Select_ID_HERE') to only effect a specific select field. 您也可以用$('#Your_Select_ID_HERE')替换$('select') $('#Your_Select_ID_HERE')以仅影响特定的选择字段。 As well you will need to call the function fixIESelect() on the body onload or via jQuery using DOM ready as I did in my code below: 以及你将需要调用函数fixIESelect()对身体onload使用DOM或通过jQuery 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();
});

I wanted this to work with selects that I added dynamically to the page, so after a lot of experimentation, I ended up giving all the selects that I wanted to do this with the class "fixedwidth", and then added the following CSS: 我希望这可以使用我动态添加到页面的选择,所以经过大量的实验,我最终给出了我想用“fixedwidth”类做的所有选择,然后添加了以下CSS:

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

and this code 和这段代码

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

A couple of things to note: 有几点需要注意:

  • In spite of the fact that my selects are all in a table, I had to do "on" to the jQuery(document).on instead of to jQuery('table#System_table').on 尽管我的选择都在一个表中,但我必须在jQuery(document).on上“on”而不是jQuery('table#System_table').on
  • In spite of the fact that the jQuery documentation says to use " mouseleave " instead of " blur ", I found that in IE7 when I moved the mouse down the drop down list, it would get a mouseleave event but not a blur . 尽管jQuery文档说使用“ mouseleave ”而不是“ blur ”,但我发现在IE7中,当我将鼠标向下移动到下拉列表时,它会得到一个mouseleave事件,但不会出现blur

For my layout, I didn't want a hack (no width increasing, no on click with auto and then coming to original). 对于我的布局,我不想要一个黑客(没有宽度增加,没有点击自动,然后来到原始)。 It broke my existing layout. 它破坏了我现有的布局。 I just wanted it to work normally like other browsers. 我只是想让它像其他浏览器一样正常工作。

I found this to be exactly like that :- 我发现这完全是这样的: -

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

A workaround if you don't care about the strange view after an option is selected (ie Select to jump to a new page): 如果在选择选项后不关心奇怪视图(即选择跳转到新页面),则解决方法:

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

Not javascript free, I am afraid too and my solution do require a js library, however, you can only use those files which you need rather than using them all, maybe best suited for those who are already using YUI for their projects or deciding which one to use. 不是javascript免费,我也害怕,我的解决方案确实需要一个js库,但是,你只能使用你需要的那些文件而不是全部使用它们,也许最适合那些已经在他们的项目中使用YUI或决定哪些一个用。 Have a look at: http://ciitronian.com/blog/programming/yui-button-mimicking-native-select-dropdown-avoid-width-problem/ 看看: http//ciitronian.com/blog/programming/yui-button-mimicking-native-select-dropdown-avoid-width-problem/

My blog post also discusses other solutions as well, one is referenced back to here on stackoverflow, why I went back to create my own SELECT element is because of simple reason, I don't like mouseover expand events. 我的博客文章也讨论了其他解决方案,其中一个在stackoverflow上被引用回来,为什么我回去创建自己的SELECT元素是因为简单的原因,我不喜欢mouseover扩展事件。 Maybe if that helps anyone else too! 也许如果这也有助于其他人!

A pure css solution : http://bavotasan.com/2011/style-select-box-using-only-css/ 一个纯粹的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> 

The jquery BalusC's solution improved by me. jquery BalusC的解决方案由我改进。 Used also: Brad Robertson's comment here . 也用过:Brad Robertson的评论

Just put this in a .js, use the wide class for your desired combos and don't forge to give it an Id. 只需将它放在.js中,使用宽类来表示所需的组合,并且不要伪造给它一个Id。 Call the function in the onload (or documentReady or whatever). 在onload(或documentReady或其他)中调用该函数。
As simple ass that :) 简单的屁股:)
It will use the width that you defined for the combo as minimun length. 它将使用您为组合定义的宽度作为最小长度。

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

Best solution: css + javascript 最佳解决方案:css + javascript

http://css-tricks.com/select-cuts-off-options-in-ie-fix/ 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"));
  });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM