在 javascript 显示后访问 DOM 元素 - Svelte

Access a DOM element in javascript after it is shown - Svelte

我正在创建自定义 select 下拉组件,简化如下:

<script lang="ts">
    let optionsOpen: boolean = false;

    function onSelectClick(e) {
        optionsOpen = !optionsOpen;
        let p = e.target.closest('.select');
        let child = p.querySelector('.options');
        console.log(child);  //always null
    }
</script>


<div class="select" on:click={onSelectClick}>
    {#if optionsOpen}
        <div class="options">
            My Options
        </div>
    {/if}
</div>

从上面你会看到,当 div 和 .select class 被点击时,选项容器打开(通过 optionsOpen 变量)。

但是,在 onSelectClick 中,我需要在 div DOM 元素打开后访问它。我可以访问 select div,但不能访问子选项 div,它总是 returns null。

我怀疑这可能是因为当我尝试访问它时 options 元素尚不可用,即使我在尝试访问之前设置了 optionsOpen 变量。

知道如何在 div 可见后访问选项吗?

我用tick函数解决了这个问题,修改后的函数如下:

<script lang="ts">
    let optionsOpen: boolean = false;

    async function onSelectClick(e) {
        optionsOpen = !optionsOpen;
        await tick();
        let p = e.target.closest('.select');
        let child = p.querySelector('.options');
        console.log(child);  //not null anymore
    }
</script>

如果可用,我会对除上述解决方案之外的其他可能解决方案感兴趣,如果上述解决方案不是处理此类情况的正确方法,我会被告知。

另一种方法是使用 Svelte action。这是一个自定义函数,在添加 DOM 节点时运行,并允许您直接访问该节点。

这比使用 querySelector 更加地道。

<script>
    let optionsOpen = false;

    function onSelectClick(e) {
        optionsOpen = !optionsOpen;
    }
    
    function adjustPosition(node) {
        // this will run when <div class="options"> is added to the DOM
        node.style.top = '300px'; // or whatever you want to do
    }
</script>


<div class="select" on:click={onSelectClick}>
    Select
    {#if optionsOpen}
        <div class="options" use:adjustPosition>
            My Options
        </div>
    {/if}
</div>