我正在写一些想法,但是评论太长了。
你在 Svelte 可以为你做的那个 REPL 中做了大量的额外工作。我同意@voscausa 的观点,您应该将事件委托给table
. 您几乎不必document.querySelector
在 Svelte 中使用。您将遍历所有行两次。您的所有事件侦听器附件都应该是标记中的属性,而不是附加在 JS 中,也不附加在初始化函数中(因此事件委托到表中)。您一直在监视鼠标位置,但您只在 中使用它onclick
,它是 aMouseEvent
并且可以访问 X 和 Y 数据。
将点击监听器切换到容器:
<div class="results" on:click={handleClick}> ... </div>
<script>
function handleClick(e) {
const tr = e.target.closest('tr');
const td = e.target.closest('td');
if (td) {
/* code */
} else {
/* code */
}
}
</script>
如果您需要将它放在整个文档上,您可以使用<svelte:window>
而不是.results
.
.option
要更新div的 css ,请执行以下操作:
<div class="options" style=`left:${optionsStyle.left}px;top:${optionsStyle.top}px`> ... </div>
<script>
let optionsStyle = {left: 0, top: 0};
function handleClick(e) {
/* code */
let left = 0, right = 0;
/* calculate left and right here */
optionsStyle = {left: e.clientX, top: e.clientY};
/* code */
}
</script>
对于切换类,请参见类指令。一个元素上可以有多个类指令。(显然,我还没有在这里完成所有逻辑。)
<div class="options" class:expand={optionsExpand}> ... </div>
<script>
let optionsExpand = false;
function handleClick(e) {
const tr = e.target.closest('tr');
const td = e.target.closest('td');
if (td) {
/* code */
optionsExpand = true;
} else {
/* code */
optionsExpand = false;
}
}
</script>
我个人会将选项弹出窗口变成它自己的组件,并将optionsExpand
布尔值作为道具传递。
像我在这里描述的那样做事情会让你以 Svelte 的心态思考,它会简化你的代码,你不需要超时,也不需要afterUpdates
函数。