如何在 Svelte 上反应性地获取 clientwidth 绑定值?
How to get clientwidth binding values reactively on Svelte?
我假设 clientWidth 没有被动更新。
问题
我想在一行中将尽可能多的电子邮件放入收件人单元格。
为此,我一次添加一个电子邮件地址。如果文本超过单元格的宽度,我会删除最后添加的电子邮件。
但是,它不会更新包含电子邮件地址的元素的宽度。无论 if 条件如何,它最终都会插入所有电子邮件。
尝试次数
- 我使用“tick”方法来反映待处理的状态更改,因为 Svelte 不会立即将更改更新到 DOM。
如果我做错了什么或有任何解决方案,请告诉我。谢谢!
<script>
import { tick } from 'svelte';
let recipients = ["aaaa@dsad.com", "djdosa@dsoad.com", "dksoadk@.com", "kofksodpofds@dsad.com"];
let recipientDisplayList = [];
let innerWidth = 0;
let recipientsWidth = 0;
$: {
if(innerWidth) {
setRecipientDisplayList();
}
}
async function setRecipientDisplayList() {
for(let i = 0; i < recipients.length; i++) {
recipientDisplayList.push(recipients[i]);
recipientDisplayList = recipientDisplayList; // https://svelte.dev/tutorial/updating-arrays-and-objects
await tick(); // wait for pending state changes to be reflected
console.log(recipients[i])
if(recipientsWidth > innerWidth) {
recipientDisplayList.pop();
break;
}
}
}
</script>
<style>
table {
table-layout: fixed;
}
th, td, table {
border-collapse: collapse;
border: 1px solid #333333;
width: 100%;
}
th, td {
max-width: 300px;
min-width: 100px;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
.recipients {
display: inline-block;
}
</style>
<table>
<tbody>
<tr>
<th>Sender</th>
<th>Recipients</th>
</tr>
<tr>
<td>Kouta Nakano</td>
<td>
<div bind:clientWidth={innerWidth}>
<span bind:clientWidth={recipientsWidth} class="recipients">
{#each recipientDisplayList as recipient}
{recipient}, 
{/each}
</span>
</div>
</td>
</tr>
</tbody>
</table>
和你一样,我希望 recipientsWidth
在 await tick()
之后更新,但不能说为什么它的行为会有所不同
当将每个电子邮件地址包装在其自己的范围内且宽度绑定到 recipientsWidth
并跟踪范围的总和以及与容器的关系 div 时,它会起作用 REPL
但是为什么不使用 text-overflow: ellipsis;
呢,所以
可见邮件地址多了?
<script>
import { onMount, tick } from 'svelte';
let recipients = ["aaaa@dsad.com", "djdosa@dsoad.com", "dksoadk@.com", "kofksodpofds@dsad.com"];
let recipientDisplayList = [];
let innerWidth = 0;
let recipientsWidth = 0;
let recipentsWidthSum = 0;
onMount(async () => {
for(let recipient of recipients) {
recipientDisplayList = [...recipientDisplayList, recipient]
await tick()
recipentsWidthSum += recipientsWidth
if(recipentsWidthSum > innerWidth) {
recipientDisplayList.pop()
recipientDisplayList = recipientDisplayList
break;
}
}
})
</script>
<table>
<tbody>
<tr>
<th>Sender</th>
<th>Recipients</th>
</tr>
<tr>
<td>Kouta Nakano</td>
<td>
<div class="client" bind:clientWidth={innerWidth}>
{#each recipientDisplayList as recipient, index}
<span bind:clientWidth={recipientsWidth} class="recipient">
{recipient}, 
</span>
{/each}
</div>
</td>
</tr>
</tbody>
</table>
<style>
table {
table-layout: fixed;
}
th, td, table {
border-collapse: collapse;
border: 1px solid #333333;
width: 100%;
}
th, td {
max-width: 300px;
min-width: 100px;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
.client {
border: 1px solid teal;
}
.recipient {
display: inline-block;
border: 1px solid magenta;
}
</style>
我假设 clientWidth 没有被动更新。
问题
我想在一行中将尽可能多的电子邮件放入收件人单元格。
为此,我一次添加一个电子邮件地址。如果文本超过单元格的宽度,我会删除最后添加的电子邮件。
但是,它不会更新包含电子邮件地址的元素的宽度。无论 if 条件如何,它最终都会插入所有电子邮件。
尝试次数
- 我使用“tick”方法来反映待处理的状态更改,因为 Svelte 不会立即将更改更新到 DOM。
如果我做错了什么或有任何解决方案,请告诉我。谢谢!
<script>
import { tick } from 'svelte';
let recipients = ["aaaa@dsad.com", "djdosa@dsoad.com", "dksoadk@.com", "kofksodpofds@dsad.com"];
let recipientDisplayList = [];
let innerWidth = 0;
let recipientsWidth = 0;
$: {
if(innerWidth) {
setRecipientDisplayList();
}
}
async function setRecipientDisplayList() {
for(let i = 0; i < recipients.length; i++) {
recipientDisplayList.push(recipients[i]);
recipientDisplayList = recipientDisplayList; // https://svelte.dev/tutorial/updating-arrays-and-objects
await tick(); // wait for pending state changes to be reflected
console.log(recipients[i])
if(recipientsWidth > innerWidth) {
recipientDisplayList.pop();
break;
}
}
}
</script>
<style>
table {
table-layout: fixed;
}
th, td, table {
border-collapse: collapse;
border: 1px solid #333333;
width: 100%;
}
th, td {
max-width: 300px;
min-width: 100px;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
.recipients {
display: inline-block;
}
</style>
<table>
<tbody>
<tr>
<th>Sender</th>
<th>Recipients</th>
</tr>
<tr>
<td>Kouta Nakano</td>
<td>
<div bind:clientWidth={innerWidth}>
<span bind:clientWidth={recipientsWidth} class="recipients">
{#each recipientDisplayList as recipient}
{recipient}, 
{/each}
</span>
</div>
</td>
</tr>
</tbody>
</table>
和你一样,我希望 recipientsWidth
在 await tick()
之后更新,但不能说为什么它的行为会有所不同
当将每个电子邮件地址包装在其自己的范围内且宽度绑定到 recipientsWidth
并跟踪范围的总和以及与容器的关系 div 时,它会起作用 REPL
但是为什么不使用 text-overflow: ellipsis;
呢,所以
可见邮件地址多了?
<script>
import { onMount, tick } from 'svelte';
let recipients = ["aaaa@dsad.com", "djdosa@dsoad.com", "dksoadk@.com", "kofksodpofds@dsad.com"];
let recipientDisplayList = [];
let innerWidth = 0;
let recipientsWidth = 0;
let recipentsWidthSum = 0;
onMount(async () => {
for(let recipient of recipients) {
recipientDisplayList = [...recipientDisplayList, recipient]
await tick()
recipentsWidthSum += recipientsWidth
if(recipentsWidthSum > innerWidth) {
recipientDisplayList.pop()
recipientDisplayList = recipientDisplayList
break;
}
}
})
</script>
<table>
<tbody>
<tr>
<th>Sender</th>
<th>Recipients</th>
</tr>
<tr>
<td>Kouta Nakano</td>
<td>
<div class="client" bind:clientWidth={innerWidth}>
{#each recipientDisplayList as recipient, index}
<span bind:clientWidth={recipientsWidth} class="recipient">
{recipient}, 
</span>
{/each}
</div>
</td>
</tr>
</tbody>
</table>
<style>
table {
table-layout: fixed;
}
th, td, table {
border-collapse: collapse;
border: 1px solid #333333;
width: 100%;
}
th, td {
max-width: 300px;
min-width: 100px;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
.client {
border: 1px solid teal;
}
.recipient {
display: inline-block;
border: 1px solid magenta;
}
</style>