当用户想要选择一个选项后,如何扩展“选择”选项的宽度

34

也许这是一个简单的问题,也许不是。我有一个选择框,我在代码中硬编码了它的宽度,比如说120像素。

<select style="width: 120px">
  <option>REALLY LONG TEXT, REALLY LONG TEXT, REALLY LONG TEXT</option>
  <option>ABC</option>
</select>

我希望能够展示第二个选项,以便用户可以看到完整的文本长度。

和其他一切一样。这在Firefox中运行良好,但在Internet Explorer6中无法正常工作。


一个简单的解决方法就是在那些较短的选项中插入空格(&nbsp;)。 - undefined
13个回答

13

我通过以下代码解决了我的问题:

<div style="width: 180px; overflow: hidden;">
   <select style="width: auto;" name="abc" id="10">
     <option value="-1">AAAAAAAAAAA</option>
     <option value="123">123</option>
   </select>
</div>

希望对你有所帮助!


1
这是一个有趣的修复。我唯一看到的问题是选择框右侧缺少向下指向箭头,这可能会让用户感到困惑。 - styfle
我已经编辑过了,以便与代码片段一起测试,但似乎并没有起作用。 - João Pimentel Ferreira
1
请检查我的解决方案:它完全可行:https://dev59.com/M3VC5IYBdhLWcg3wcgqd#55343177 - João Pimentel Ferreira
1
很好的修复。小改动,"style="width: 180px; overflow: hidden;""不必要(实际上正是导致下箭头丢失的原因,正如@styfle所指出的)。选择和width:auto就足够了。 - PravyNandas

12
如果您已经在固定宽度的<select>中有此选项,并且您不想通过编程更改其宽度,除非您稍微有些创意,否则可能会运气不佳。
  • 您可以尝试为每个选项设置title属性。 这是非标准HTML(如果您在意此轻微违规),但IE(以及Firefox)将在鼠标悬停时在鼠标弹出窗口中显示整个文本。
  • 您可以使用JavaScript在用户选择某些内容时在某个定位的DIV中显示文本。 在我看来,这是一种 不太好的方法,因为它需要JavaScript才能正常工作,并且只有在选中某项后才能工作。 在更改值之前,选择框不会触发任何事件。
  • 您根本不使用选择框,而是使用其他标记和CSS实现其功能。 不是我最喜欢的,但我想提一下。

如果您稍后通过JavaScript添加了一个较长的选项,请查看此处:如何在IE中动态更新HTML“select”框


6

虽然这是一个很老的问题,但是这里有一个解决方案。下面是一个使用jquery的代码片段。它使用了一个临时的辅助select,将主要选择的选项复制到其中,这样就可以评估主select应该具有的真实宽度。

$('select').change(function(){
  var text = $(this).find('option:selected').text()
  var $aux = $('<select/>').append($('<option/>').text(text))
  $(this).after($aux)
  $(this).width($aux.width())
  $aux.remove()
}).change()
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select>
  <option>ABC</option>
  <option>REALLY LONG TEXT, REALLY LONG TEXT, REALLY LONG TEXT</option>
</select>


1
这个很好用。如果最长的选项不是第一个怎么办?它仍然会以最长选项的宽度加载,然后在更改时调整大小。我会试着调整一下,但也许你已经考虑过这个问题了... - Jeff Lindblom
@JeffLindblom 我按照你的建议交换了元素并稍微修改了代码。为了解决这个问题,你只需要在声明后“触发”事件即可。现在可以进行测试了。 - João Pimentel Ferreira
@JoãoPimentelFerreira 如果没有使用jQuery,你会如何在原生JS中完成相同的事情? - AziCode
1
@AziCode 给你链接:https://dev59.com/M3VC5IYBdhLWcg3wcgqd#67240166 - kilian

5

将它放在一个div中并给它一个id。

<div id=myForm>

然后创建一个非常简单的CSS与之配合使用。
#myForm select { 
width:200px; }

#myForm select:focus {
width:auto; }

这就是你所需要的。


5

我在我的Bootstrap页面中通过将选择器的min-width和max-width设置为相同的值,然后将select:focus设置为auto来解决了这个问题。

select {
  min-width: 120px;
  max-width: 120px;
}
select:focus {
  width: auto;
}
<select style="width: 120px">
  <option>REALLY LONG TEXT, REALLY LONG TEXT, REALLY LONG TEXT</option>
  <option>ABC</option>
</select>


@MuneebMirza,请检查我的解决方案,它完美地工作:https://dev59.com/M3VC5IYBdhLWcg3wcgqd#55343177 - João Pimentel Ferreira

4
这个例子可以模拟您所需的大部分行为:
  <!--

     I found this works fairly well.

  -->

  <!-- On page load, be sure that something else has focus. -->
  <body onload="document.getElementById('name').focus();">
  <input id=name type=text>

  <!-- This div is for demonstration only.  The parent container may be anything -->
  <div style="height:50; width:100px; border:1px solid red;">

  <!-- Note: static width, absolute position but no top or left specified, Z-Index +1 -->
  <select
   style="width:96px; position:absolute; z-index:+1;"
   onactivate="this.style.width='auto';"
   onchange="this.blur();"
   onblur="this.style.width='96px';">
  <!-- "activate" happens before all else and "width='auto'" expands per content -->
  <!-- Both making a selection and moving to another control should return static width -->

  <option>abc</option>
  <option>abcdefghij</option>
  <option>abcdefghijklmnop</option>
  <option>abcdefghijklmnopqrstuvwxyz</option>

  </select>

  </div>

  </body>

  </html>

这将覆盖一些按键行为。

我将其复制到http://jsfiddle.net中,似乎无法根据所选选项的文本长度更改选择大小。 - Manohar Reddy Poreddy

3

即使这个问题是从2008年开始的,仍然有一些情况你希望选择框的宽度与当前选择相匹配而不是最长的选项。下面是一个现代的解决方案:

它基本上和这个答案的原则差不多,只是没有使用jQuery。

  1. 获取选择元素并监听其更改。
  2. 创建一个新的选择元素和选项,并将当前selectedIndex的文本传递给选项。
  3. 向新的选择元素添加position: fixedvisibility: hidden样式。这确保了它不会影响您的布局,但其边界框仍然可以被测量。
  4. 将选项附加到选择中。
  5. 将选择附加到原始选择元素。
  6. 使用getBoundingClientRect().width获取该新元素所需的尺寸。
  7. 根据新元素的尺寸设置原始元素的宽度。
  8. 删除新的元素。
  9. 分派更改事件以最初触发此逻辑。

const select = document.querySelector('select')

select.addEventListener('change', (event) => {
  let tempSelect = document.createElement('select'),
      tempOption = document.createElement('option');

  tempOption.textContent = event.target.options[event.target.selectedIndex].text;
  tempSelect.style.cssText += `
      visibility: hidden;
      position: fixed;
      `;
  tempSelect.appendChild(tempOption);
  event.target.after(tempSelect);
  
  const tempSelectWidth = tempSelect.getBoundingClientRect().width;
  event.target.style.width = `${tempSelectWidth}px`;
  tempSelect.remove();
});

select.dispatchEvent(new Event('change'));
<select>
  <option>Short option</option>
  <option>Some longer option</option>
  <option>An very long option with a lot of text</option>
</select>


1
我使用最少量的JS基于数据属性和隐藏CSS伪元素创建了具有自动展开功能的样式选择元素。

Array.from(document.querySelectorAll('.js-select-auto-expand'), (input) => {
  let parent = input.parentNode;
  
  function updateSize() {
    parent.dataset.selectAutoExpand = input.value
  }
  
  input.addEventListener('input', updateSize);
  
  updateSize();
});
*,
*::before,
*::after {
  box-sizing: border-box;
}

body {
  padding: 2rem 4rem;
  line-height: 1.5;
  color: gray;
}

.article-test {
  line-height: 2.5;
}

.select-auto-expand {
  position: relative;
  display: inline-block;
  min-width: 2rem;
  width: auto;
  height: 30px;
  line-height: 28px;
  padding: 0 10px;
  vertical-align: baseline;
  border: 1px solid black;
  background-color: transparent;
  color: #fafafa;
  font-size: 1rem;
}
.select-auto-expand .select-auto-expand__select {
  position: absolute;
  top: 0px;
  bottom: 0;
  left: 0;
  right: 0;
  width: 100%;
  min-width: 1em;
  height: 100%;
  margin: 0 2px;
  padding: 0 8px;
  -webkit-appearance: none;
     -moz-appearance: none;
          appearance: none;
  border-radius: 0;
  border: 0;
  background: transparent;
  font: inherit;
}
.select-auto-expand::after {
  content: attr(data-select-auto-expand);
  display: inline-block;
  width: 100%;
  min-width: 1em;
  white-space: pre-wrap;
  font: inherit;
  line-height: inherit;
  color: inherit;
  background: transparent;
  visibility: hidden;
  opacity: 0;
}
.select-auto-expand:focus-within {
  outline: 3px solid rgba(0, 0, 255, 0.3);
}
.select-auto-expand:focus-within input:focus {
  outline: none;
}
<form action="#" class="article-test">

  <p>
    Adipisci ipsum debitis quaerat commodi tenetur? Amet consectetur adipisicing elit. Lorem ipsum dolor sit, 
    <label class="select-auto-expand" for="pet-select">
      <select name="pets" id="pet-select" class="select-auto-expand__select js-select-auto-expand">
        <option value="select ...">select ...</option>
        <option value="sed qui">sed qui</option>
        <option value="veniam iste quis">veniam iste quis</option>
        <option value="ipsum debitis">ipsum debitis</option>
        <option value="officia excepturi repellendus aperiam">officia excepturi repellendus aperiam</option>
      </select>
    </label>
    veniam iste quis, sed qui non dolores. Porro, soluta. Officia excepturi repellendus aperiam cumque consectetur distinctio, veniam iste quis, sed qui non dolores. Adipisci ipsum debitis quaerat commodi tenetur?
  </p>

</form>

Demo: https://codepen.io/astro87/pen/dyZerdg?editors=0010

灵感来源: https://filamentgroup.github.io/select-css/demo/ https://codepen.io/shshaw/full/bGNJJBE

1
使用jQuery的一个简单解决方案(但如果您真的不熟悉JS,我可以用eventListener代码进行回传)在IE中为现有站点使用以下内容:
if (jQuery.browser.msie) {
  jQuery('#mySelect').focus(function() {
    jQuery(this).width('auto');
  }).bind('blur change', function() {
    jQuery(this).width('100%');
  });
};

当然,可以使用一个变量(var cWidth = jQuery('#mySelect').width();)来存储先前的宽度,但这就是我们需要的一切,以使其按照您的预期工作。

1

好的,这个选项相当“hackish”,但应该可以工作。

$(document).ready( function() {
$('#select').change( function() {
    $('#hiddenDiv').html( $('#select').val() );
    $('#select').width( $('#hiddenDiv').width() );
 }
 }

这当然需要一个隐藏的 div。

<div id="hiddenDiv" style="visibility:hidden"></div>

哦,你需要 jQuery


1
为什么在涉及 JavaScript 问题时似乎没有绕过 jQuery 的方法?将 jQuery 添加到您的网站以解决此问题是杀鸡焉用牛刀。 - Tomalak
大多数情况下,我总是使用jQuery(像大多数从PHP开始学习并开始使用JavaScript的人一样),因为普通的JavaScript让我很烦。对我来说,编写jQuery更容易且更快速。 - Pim Jager
1
JavaScript是一种美丽的语言(不像PHP那样靠近光谱的另一端),只有复杂的DOM操作令人讨厌。琐碎的DOM操作是...嗯,琐碎的。 :-) 不需要完整的JS框架。 - Tomalak
我同意,问题是关于标准化的Javascript,而不是非标准的jQuery。它们的好坏或一个人对它们的喜好并不重要。我们会很快开始看到针对Cobol问题的“只需使用C”的回答吗? - buti-oxa
首先,如果提问者不想使用答案,他可以选择不使用它。其次,这是唯一一个完整回答实际上回答了问题。而且你可以很容易地用标准的Javascript替换掉这里的所有jQuery。所以如果你想这么做,就去做吧。 - Pim Jager

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接