Svelte组件像素高度测量问题:获值始终为undefined
问题:测量Svelte SMUI组件高度返回undefined
尝试测量Svelte中@smui/data-table的Head组件高度时,始终得到undefined值。给组件包裹HTML容器后能正常获取高度,但不想采用这种方案。代码如下:
<script lang='ts'> import { onMount } from 'svelte'; import DataTable, { Head, Row, Cell, } from '@smui/data-table'; let headElement; let headHeight = 0; const measureHead = () => { if(headElement) { headHeight = headElement.offsetHeight } } onMount(() => { measureHead(); console.log("Height: ", headHeight) //Returns undefined }) </script> <DataTable table$aria-label="User list" style="width: 100%;" > <Head bind:this={headElement}> <Row> <Cell style="width: 100%;">Title</Cell> <Cell>Type</Cell> <Cell numeric>Distance</Cell> </Row> </Head> </DataTable>
原因
bind:this绑定到<Head>组件时,获取到的是Svelte组件实例,而非底层的DOM元素。组件实例没有offsetHeight属性,因此返回undefined。
解决方案
方法1:访问组件实例暴露的DOM元素引用
部分SMUI组件会将内部DOM元素通过属性暴露出来,可以尝试访问组件实例的element属性(具体可参考SMUI组件文档):
const measureHead = () => { if (headElement && headElement.element) { headHeight = headElement.element.offsetHeight; } }
方法2:直接给内部DOM元素加ID获取
给Head组件内的根DOM元素(比如Row)添加ID,直接通过document.getElementById获取:
<DataTable table$aria-label="User list" style="width: 100%;" > <Head> <Row id="table-header-row"> <Cell style="width: 100%;">Title</Cell> <Cell>Type</Cell> <Cell numeric>Distance</Cell> </Row> </Head> </DataTable>
对应脚本修改:
onMount(() => { const headerRow = document.getElementById('table-header-row'); if (headerRow) { headHeight = headerRow.offsetHeight; console.log("Height: ", headHeight); } })
方法3:使用ResizeObserver监听高度变化(推荐动态场景)
如果表头高度可能随内容、布局变化,用ResizeObserver可以实时获取高度:
<script lang='ts'> import { onMount, onDestroy } from 'svelte'; import DataTable, { Head, Row, Cell } from '@smui/data-table'; let headHeight = 0; let headerRow; let observer; onMount(() => { headerRow = document.getElementById('table-header-row'); if (headerRow) { observer = new ResizeObserver(entries => { headHeight = entries[0].contentRect.height; console.log("Height: ", headHeight); }); observer.observe(headerRow); } }); onDestroy(() => { if (observer && headerRow) { observer.unobserve(headerRow); } }); </script> <DataTable table$aria-label="User list" style="width: 100%;" > <Head> <Row id="table-header-row"> <Cell style="width: 100%;">Title</Cell> <Cell>Type</Cell> <Cell numeric>Distance</Cell> </Row> </Head> </DataTable>
内容的提问来源于stack exchange,提问作者nick_jj
相关产品推荐
相关产品推荐

