我应该如何将 Svelte Reactivity 与 DOM getElementById 一起使用?
How should I use Svelte Reactivity with DOM getElementById?
我有一个可滚动的 div 元素
<script>
let scrollBoxObj;
$: scrollBoxObj = document.getElementById("chat-box");
$: if (!(scrollBoxObj === undefined) && scrollBoxObj.scrollTop < scrollBoxObj.scrollHeight) {
scrollBoxObj.scrollTop = scrollBoxObj.scrollHeight;
}
</script>
<div id="scrollBox" class="h-screen w-auto chat-box border border-orange rounded">
<div id="chat-box" style="margin: 0" class="chat-box">
{#each chatBox as { user, content, type}}
<MessageBox {user} message={content} {type} />
{/each}
</div>
</div>
<style>
.chat-box {
overflow-y: auto;
}
</style>
我正在尝试在添加新消息时自动向下滚动。
但它不是反应性的。
或者我不明白反应性在 svelte 中是如何工作的。
我也尝试在 onMount 中分配 scrollBoxObj 但它仍然是相同的结果没有工作。
在 Svelte 中,当等式左侧(y
部分)发生变化时,$: x = y
的反应性开始发挥作用。
在你的代码中你有
$: scrollBoxObj = document.getElementById("chat-box");
左边有一个字符串("chat-box"),它是一个常量,永远不会改变,还有文档 也永远不会改变,这意味着反应性不会像您预期的那样工作。
使用 document.getElementById
(或任何其他选择器方法)与 Svelte 一起工作时被认为是不好的做法,因为您直接与 DOM 交互,而您的 DOM 应该反映你的状态。简而言之:不要这样做。
Svelte 为您提供了一种将 DOM 节点(如 div)绑定到变量的简单方法,只需添加 bind:this={variable}
在您的情况下,这将变为:
<script>
let scrollbox
</script>
<div bind:this={scrollbox}>
...
</div>
反应式声明(if块)将在其中任何内容发生变化时执行,在您的情况下是滚动框:
$: if (scrollBoxObj && scrollBoxObj.scrollTop < scrollBoxObj.scrollHeight) {
scrollBoxObj.scrollTop = scrollBoxObj.scrollHeight;
}
这里再次注意,只有当scrollbox改变时才会触发,一旦绑定就不会再触发(比如当用户滚动时,它不会做任何事情)为此,您可能应该使用 on:scroll
事件。
我有一个可滚动的 div 元素
<script>
let scrollBoxObj;
$: scrollBoxObj = document.getElementById("chat-box");
$: if (!(scrollBoxObj === undefined) && scrollBoxObj.scrollTop < scrollBoxObj.scrollHeight) {
scrollBoxObj.scrollTop = scrollBoxObj.scrollHeight;
}
</script>
<div id="scrollBox" class="h-screen w-auto chat-box border border-orange rounded">
<div id="chat-box" style="margin: 0" class="chat-box">
{#each chatBox as { user, content, type}}
<MessageBox {user} message={content} {type} />
{/each}
</div>
</div>
<style>
.chat-box {
overflow-y: auto;
}
</style>
我正在尝试在添加新消息时自动向下滚动。 但它不是反应性的。 或者我不明白反应性在 svelte 中是如何工作的。 我也尝试在 onMount 中分配 scrollBoxObj 但它仍然是相同的结果没有工作。
在 Svelte 中,当等式左侧(y
部分)发生变化时,$: x = y
的反应性开始发挥作用。
在你的代码中你有
$: scrollBoxObj = document.getElementById("chat-box");
左边有一个字符串("chat-box"),它是一个常量,永远不会改变,还有文档 也永远不会改变,这意味着反应性不会像您预期的那样工作。
使用 document.getElementById
(或任何其他选择器方法)与 Svelte 一起工作时被认为是不好的做法,因为您直接与 DOM 交互,而您的 DOM 应该反映你的状态。简而言之:不要这样做。
Svelte 为您提供了一种将 DOM 节点(如 div)绑定到变量的简单方法,只需添加 bind:this={variable}
在您的情况下,这将变为:
<script>
let scrollbox
</script>
<div bind:this={scrollbox}>
...
</div>
反应式声明(if块)将在其中任何内容发生变化时执行,在您的情况下是滚动框:
$: if (scrollBoxObj && scrollBoxObj.scrollTop < scrollBoxObj.scrollHeight) {
scrollBoxObj.scrollTop = scrollBoxObj.scrollHeight;
}
这里再次注意,只有当scrollbox改变时才会触发,一旦绑定就不会再触发(比如当用户滚动时,它不会做任何事情)为此,您可能应该使用 on:scroll
事件。