javascript - 我应该如何将 Svelte Reactivity 与 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中,$: x = y
当等式左侧(y
-部分)发生变化时,反应性就会开始。
在您的代码中,您有
$: scrollBoxObj = document.getElementById("chat-box");
在左侧,我们有一个字符串 ( "chat-box" ),它是一个常量并且永远不会改变,还有一个文档也永远不会改变,这意味着反应不会像你期望的那样工作。
在使用 Svelte 时,使用document.getElementById
(或任何其他选择器方法)被认为是不好的做法,因为您直接与 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;
}
请再次注意,这只会在滚动框更改时触发,一旦绑定,您将不会重新触发(例如,当用户滚动时,它不会做任何事情),因为您可能应该使用on:scroll
事件。
推荐阅读
- swift - 如何在 Swift 中嵌入文件?
- c++ - 使用 `emplace_back` 而不是 `push_back` 时没有缩小警告
- excel - Excel 数据中的变音符号
- mysql - 将视图查询转换为 mysql 查询
- python - IPython (jupyter) 与 Python (PyCharm) 的性能对比
- python - np.where 计算年龄组指数
- wordpress - 如何在 LOCALHOST 中增加 WordPress 中的最大上传文件大小
- javascript - 如何动态更改类中的方法?
- java - 如何导入生成文件夹中的java类?
- webpack - webpack.config:包含参数