根据所选OPTION的宽度自动调整SELECT元素的大小

Th3*_*ist 28 jquery select resize dom-manipulation autoresize

我有这个select元素与option它不同.通常select元素会从最大option元素获得宽度,但我希望select元素的默认option值宽度更短.当用户选择另一个元素时option,该select元素应调整自身大小,以便整个文本始终在元素中可见.

$(document).ready(function() {
    $('select').change(function(){
        $(this).width($('select option:selected').width());
    });
});
Run Code Online (Sandbox Code Playgroud)

问题:

  • 在Chrome(Canary)上,它的返回宽度始终为0.
  • 在Firefox上,选择较短的选项时,会添加宽度并且不会调整大小.
  • Safari:与Chrome相同的结果.

演示@ JSFiddle

kma*_*mas 43

你是对的,没有简单或内置的方法来获得特定选择选项的大小.这是一个做你想要的JsFiddle.

它的最新版本是可以的Chrome, Firefox, IE, Opera and Safari.

我添加了一个隐藏的选择#width_tmp_select来计算#resizing_select我们想要自动调整大小的可见选区的宽度.我们将隐藏选择设置为具有单个选项,其选项的文本是当前所选选项的选项.然后我们使用隐藏选择的宽度作为可见选择的宽度.请注意,使用隐藏的跨度而不是隐藏的选择效果非常好,但宽度将稍微偏离,如下面的注释中的sami-al-subhi所指出的那样.

$(document).ready(function() {
  $('#resizing_select').change(function(){
    $("#width_tmp_option").html($('#resizing_select option:selected').text()); 
    $(this).width($("#width_tmp_select").width());  
  });
});
Run Code Online (Sandbox Code Playgroud)
#resizing_select {
  width: 50px;
} 
 
#width_tmp_select{
  display : none;
} 
Run Code Online (Sandbox Code Playgroud)
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.js"></script>

<select id="resizing_select">
  <option>All</option>
  <option>Longer</option>
  <option>A very very long string...</option>
</select>

<select id="width_tmp_select">
  <option id="width_tmp_option"></option>
</select>
Run Code Online (Sandbox Code Playgroud)

  • 这是一个纯 javascript 尝试版本:http://jsfiddle.net/FSsG8/635/ 你也可以通过尝试匹配两个选择之间的字体来获得一些吸引力,有点相似:http://stackoverflow.com/问题/6385533/how-to-change-width-of-the-select-element-as-per-the-selected-option/6385741#6385741 (2认同)

Kyl*_*Mit 15

这是我刚刚为这个问题编写的一个插件,它动态创建并销毁了一个模拟器,span因此它不会使你的html混乱.这有助于分离问题,允许您委派该功能,并允许跨多个元素轻松重用.

在任何地方都包含这个JS:

(function($, window){
  var arrowWidth = 30;

  $.fn.resizeselect = function(settings) {  
    return this.each(function() { 

      $(this).change(function(){
        var $this = $(this);

        // create test element
        var text = $this.find("option:selected").text();
        var $test = $("<span>").html(text).css({
            "font-size": $this.css("font-size"), // ensures same size text
            "visibility": "hidden"               // prevents FOUC
        });


        // add to parent, get width, and get out
        $test.appendTo($this.parent());
        var width = $test.width();
        $test.remove();

        // set select width
        $this.width(width + arrowWidth);

        // run on start
      }).change();

    });
  };

  // run by default
  $("select.resizeselect").resizeselect();                       

})(jQuery, window);
Run Code Online (Sandbox Code Playgroud)

您可以通过以下两种方式之一初始化插件:

  1. HTML - 将类添加.resizeselect到任何select元素:

    <select class="btn btn-select resizeselect">
      <option>All</option>
      <option>Longer</option>
      <option>A very very long string...</option>
    </select>
    
    Run Code Online (Sandbox Code Playgroud)
  2. JavaScript - 调用.resizeselect()任何jQuery对象:

    $("select").resizeselect()
    
    Run Code Online (Sandbox Code Playgroud)

这是jsFiddle中演示

这是Stack Snippets中的演示:

(function($, window){
  var arrowWidth = 30;

  $.fn.resizeselect = function(settings) {  
    return this.each(function() { 

      $(this).change(function(){
        var $this = $(this);

        // create test element
        var text = $this.find("option:selected").text();
        var $test = $("<span>").html(text).css({
        	"font-size": $this.css("font-size"), // ensures same size text
            "visibility": "hidden"               // prevents FOUC
        });
        
        // add to parent, get width, and get out
        $test.appendTo($this.parent());
        var width = $test.width();
        $test.remove();

        // set select width
        $this.width(width + arrowWidth);

        // run on start
      }).change();

    });
  };

  // run by default
  $("select.resizeselect").resizeselect();                       

})(jQuery, window);
Run Code Online (Sandbox Code Playgroud)
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.js"></script>

<select class="resizeselect">
  <option>All</option>
  <option>Longer</option>
  <option>A very very long string...</option>
</select>
Run Code Online (Sandbox Code Playgroud)

更新以包括GarywooEric Warnke的尺寸建议


0st*_*ne0 7

基于@Kmas答案的纯 Javascript 2022 版本。


function resize(event) {
  const fakeEl = document.querySelector('#fakeEl');
  const option = event.target.options[event.target.selectedIndex];
  
  fakeEl[0].innerHTML = event.target.value;
  event.target.style.width = fakeEl.getBoundingClientRect().width + 'px';
}

for (let e of document.querySelectorAll('select.autoresize')) {
  e.onchange = resize;
  e.dispatchEvent(new Event('change'));
}
Run Code Online (Sandbox Code Playgroud)
<select class='autoresize'>
    <option>Foo</option>
    <option>FooBar</option>
    <option>FooBarFooBarFooBar</option>
</select>

<select id='fakeEl' style='visibility: hidden'><option></option></select>
Run Code Online (Sandbox Code Playgroud)


你可能不需要 Jquery


Joã*_*ira 6

这里的工作解决方案利用了一种临时辅助工具select,将从主选择中选择的选项克隆到其中,以便可以评估主工具select应具有的真实宽度。

这里的好处是,您只需添加此代码即可,它适用于每个选择,因此无需ids额外的命名。

$('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()
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select>
  <option>REALLY LONG TEXT, REALLY LONG TEXT, REALLY LONG TEXT</option>
  <option>ABCDEFGHIJKL</option>
  <option>ABC</option>
</select>
Run Code Online (Sandbox Code Playgroud)


kil*_*ian 5

这是一个更现代的普通 JS 方法来解决这个问题。它或多或少与这个答案中的原理相同,只是没有 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'));
Run Code Online (Sandbox Code Playgroud)
<select>
  <option>Short option</option>
  <option>Some longer option</option>
  <option>A very long option with a lot of text</option>
</select>
Run Code Online (Sandbox Code Playgroud)