动态设置选择元素的宽度等于其选项的内容宽度

时间:2019-09-04 10:25:58

标签: javascript css angular typescript dom

我正在尝试使选择元素的宽度等于它的选项文本宽度(以角度为单位)。

我的HTML组件看起来像这样:

<form [formGroup]="profileForm">
  ...
  <select (change)="adjustSelectWidth($event.target)" formControlName="members">
    <option value="1">Me</option>
    <option value="2">Me, my spouse</option>
    <option value="3">Me, my spouse and my kids</option>
  </select>
  ...
</form>

我尝试过的事情:

  • 使用clientWidth获取选项元素的宽度,然后将其应用于选择元素,但宽度为0。
export class AppComponent  {
  profileForm = new FormGroup({
    members : new FormControl(''),
  })

  adjustSelectWidth(e){
    const optionValue = this.profileForm.get('members').value;
    const optionWidth = document.querySelector(`option[value="${optionValue}"]`).clientWidth;
    e.style.width= optionWidth + "px"
  }
}
  • 获取选项的innerHTML长度,然后以固定像素可变地获取,但不是动态选项
export class AppComponent  {
  profileForm = new FormGroup({
    members : new FormControl(''),
  })

  adjustSelectWidth(e){
    const optionValue = this.profileForm.get('members').value;
    const optionTextLength = document.querySelector(`option[value="${optionValue}"]`).innerHTML.length;
    e.style.width= optionTextLength*8 + "px";
  }
}
  • 将选项的innerHTML附加到一个用于测量宽度的span元素,但是当我将其应用于select元素时,那个跨度clientWidth并不准确
export class AppComponent  {
  //This temp is bind to a span via string interpolation {{...}}
  temp:string;

  profileForm = new FormGroup({
    members : new FormControl(''),
  })

  adjustSelectWidth(e){
    const optionValue = this.profileForm.get('members').value;
    const optionText = document.querySelector(`option[value="${optionValue}"]`).innerHTML;
    this.temp = optionText;
    const spanWidth = document.querySelector(`.temp`).clientWidth;
    e.style.width = spanWidth + "px";
  }
}

由于即时通讯使用的是我的语言,所以我不愿使用JQuery。此外,为什么clientWidth似乎不能解决我的问题

我创建了一个stackbliz示例:https://stackblitz.com/edit/angular-bbimkz

1 个答案:

答案 0 :(得分:1)

有一种方法可以测量文本宽度。我认为它足够可靠,但是在性能方面可能有些昂贵,这当然取决于您的应用程序。 (Stackblitz中的简单示例没有性能问题。)

该方法是将隐藏元素实际添加到包含要测量的文本的文档中,阅读clientWidth,然后立即删除该元素。

修改adjustSelectWidth()如下:

adjustSelectWidth(e: HTMLSelectElement){
  // assuming something is always selected, please test!
  const displayedText = e.options[e.selectedIndex].innerText;
  const dummy = document.createElement('div');
  dummy.innerText = displayedText;
  dummy.style.position = 'absolute';
  dummy.style.visibility = 'hidden';
  document.body.insertBefore(dummy, document.body.firstChild);
  const measuredWidth = dummy.clientWidth;
  document.body.removeChild(dummy);
  e.style.width = (measuredWidth + 30) + 'px'
}

修改后的Stackblitz:https://stackblitz.com/edit/angular-mpjxbd?file=src/app/app.component.ts-在最新的Firefox,Chrome,Edge中进行了测试