简体   繁体   English

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

[英]Set select element width equal to it's option's content width dynamically

Im trying to make select element width equal to it's option text width in angular.我试图使选择元素宽度等于它的角度选项文本宽度。

My HTML component simply look like this:我的 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>

What I have tried:我尝试过的:

  • Get the option element width using clientWidth then apply that to select element but that width is 0.使用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"
  }
}
  • Get the option's innerHTML length then mutiply it with a fixed pixel but it not a dynamic option获取选项的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";
  }
}
  • Append the options's innerHTML to a span element for measuring width, but then that span clientWidth does not accurate when I apply it's to the select element将选项的innerHTML附加到 span 元素以测量宽度,但是当我将它应用于 select 元素时,span 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";
  }
}

Since im using angular, i prefer not to use JQuery.由于我使用 angular,我不想使用 JQuery。 Additionally, why the clientWidth seem to not solve my problem here另外,为什么clientWidth在这里似乎不能解决我的问题

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

There is a way to measure text width.有一种方法可以测量文本宽度。 I think it is sufficiently reliable, but might be a bit expensive in terms of performance, depending on your app of course.我认为它足够可靠,但在性能方面可能有点贵,这当然取决于您的应用程序。 (The simplistic example in Stackblitz has no performance problem.) (Stackblitz 中的简单示例没有性能问题。)

The method is to actually append a hidden element to the document containing the text you want to measure, read the clientWidth , and remove the element immediately.该方法实际上是在包含要测量的文本的文档中附加一个隐藏元素,读取clientWidth ,然后立即删除该元素。

Modify adjustSelectWidth() as follows:修改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'
}

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

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

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