点击带fa-icon的子按钮时,如何正确获取父HTML元素的宽度?
解决点击图标时无法正确获取表格列宽的问题
问题场景
我定义了数组leftPlace用于存储列宽:
leftPlace = <(number | undefined)[]>[];
HTML结构如下,点击按钮调用方法提取列宽:
<th class="table-cell"> <div class="table-cell-content date-column"> <button (click)="sendLeft($event.target)" style="color: white;"> <fa-icon [icon]="['fas', 'location-pin']"></fa-icon> </button> </div> </th>
提取列宽的方法:
sendLeft(value?: EventTarget | null) { if (value instanceof Element) { this.leftPlace[this.columnCounter] = value.parentElement?.parentElement?.getBoundingClientRect().width; this.columnCounter++; } }
点击<fa-icon>时,获取到的是图标的宽度而非目标<th>的宽度,但使用普通文本内容时可正常获取父元素宽度。
原因分析
$event.target会指向实际被点击的DOM元素:点击图标时它就是<fa-icon>,此时value.parentElement是<button>,value.parentElement?.parentElement是<div class="table-cell-content">,并非目标<th>,所以拿到的不是列宽;而点击普通文本时,target是按钮或文本节点,层级匹配能正确找到<th>。
解决方案
方案1:使用$event.currentTarget替代$event.target
currentTarget始终指向绑定了事件的元素(即<button>),不受子元素点击影响。修改HTML的点击事件:
<button (click)="sendLeft($event.currentTarget)" style="color: white;"> <fa-icon [icon]="['fas', 'location-pin']"></fa-icon> </button>
此时方法里value是按钮元素,value.parentElement?.parentElement正好是<th>,能正确获取列宽。
方案2:用closest直接查找目标<th>
不管点击的是哪个子元素,直接通过closest方法向上查找最近的.table-cell元素,DOM结构变化也不用调整层级。修改sendLeft方法:
sendLeft(value?: EventTarget | null) { if (value instanceof Element) { const thElement = value.closest('.table-cell'); this.leftPlace[this.columnCounter] = thElement?.getBoundingClientRect().width; this.columnCounter++; } }
这种方式无需修改HTML,兼容性好且更健壮。
方案3:将事件绑定到<th>元素(如果业务允许)
如果点击整个列头都需要触发列宽提取,可以把点击事件直接绑定到<th>上:
<th class="table-cell" (click)="sendLeft($event.currentTarget)"> <div class="table-cell-content date-column"> <button style="color: white;"> <fa-icon [icon]="['fas', 'location-pin']"></fa-icon> </button> </div> </th>
对应的方法简化为:
sendLeft(value?: EventTarget | null) { if (value instanceof Element) { this.leftPlace[this.columnCounter] = value.getBoundingClientRect().width; this.columnCounter++; } }
内容的提问来源于stack exchange,提问作者Gregster
相关产品推荐
相关产品推荐

