on:animationend无法访问bind:this svelte(未定义)

问题描述 投票:0回答:3

我想使用

querySelector()
,但我发现 Svelte 有另一种方法可以做到这一点。

通过使用

bind:this


问题是有时它可以工作,但大多数时候它永远不会工作

通过输出

undefined

这是一个简单的例子:

<script>
  let thisDiv;

  console.log(thisDiv) // ❌ "undefined" ✅ "<div>"
</script>

<div bind:this={thisDiv}>hello world</div>

真正的错误

但真正的问题在这里

因为我现在不需要

console.log

我之前写的东西只是为了让你了解这个bug
这样我就可以开始提供更多信息。

因为我有一个使用该变量的函数
并在事件“

on:animationend
”开始时调用该函数。

像这样:

<div
  bind:this={thisDiv}
  on:animationend={doStuff()}
></div>

问题是

animationend
仍然在 console.log
thisDiv
undefined

也许是速度问题?

是的,好的...

但是CSS中的动画只有50毫秒长。还尝试过 0.5s

CSS 不会阻止 javascript,因此当 CSS 执行动画时,js 将继续工作(据我所知)

和 0.5 秒,我认为对于做一个简单的

bind:this
(querySelector)

来说已经很多了

这怎么可能?半秒后就得到了一个正常的querySelector,但仍然什么也没有。


源代码

这里是 REPL 在线 svelte 源代码示例:

https://svelte.dev/repl/b49d019ce7f8426b80295158b091520f?version=3.50.1

确保取消 child.svelte 中第 9 行的注释

...或者直接看这个

App.svelte

<script>
    import Child from "./Child.svelte"
    
    function generateExample() {
        let output = [];
        
        for(let i=0; i<=100; i++) {
            output = [
                ...output, `text ${i}`
            ]
        }
        
        return output;
    }
    
  let array = generateExample()
</script>

{#each array as item, index}
   <Child {index}>
      {item}
   </Child>
{/each}

儿童苗条

<script>
  export let index;
  const DELAY = 50;
  
  let thisDiv;

    // UNCOMMENT THE NEXT LINE
  function doStuff() {
         // thisDiv.scrollIntoView(); 
  }
</script>

<div
  style="--delay:{index * DELAY}ms;"
  bind:this={thisDiv}
  on:animationend={doStuff()}
  >
  <slot></slot>
</div>

<style>
  div {
    animation: show var(--delay);
  }

  @keyframes show {
    from {
      translate: 100vw;
    }
    to {
      translate: 0;
    }
  }
</style>
javascript css dom-events svelte
3个回答
2
投票

实际上,您的代码有问题,您调用了处理程序而不是引用它:

on:animationend={doStuff()}

应该是:

on:animationend={doStuff}

REPL

此外,您不需要

bind:this
并且可以使用事件对象:

function doStuff(e) {
    e.target.scrollIntoView();
}

REPL


1
投票

解决方案代码:

<script>
// other your code

$: if(thisDiv) {
  thisDiv.addEventListener("animationend", () => {
    thisDiv.scrollIntoView()
  })
}
</script>

并且由于

if
检查和本机 JavaScript 代码,也没有错误。


发生错误是因为当您编写

bind:this
时,该值无法直接获得(但这并不意味着速度很慢)


那么如何解决呢?

我相信

$: if(thisDiv)
应该能够成功。

所以将所有逻辑放入

IF


这也意味着您不需要再使用属性

on:animationend
,因为它不在
IF


所以我们颠倒了逻辑,

  • 首先,我们确保绑定不是未定义的,
  • 然后我们使用 vanilla javascript 来执行逻辑(而不是精简逻辑)

编辑:

我现在看到@H.B建议了一种更简单的方法,因为你的错误只是拼写错误

doStuff()
doStuff


0
投票

问题是

animationend
立即被解雇。请参阅我的其他答案。

尝试仅记录索引/时间:

function doStuff() {
    console.log(index, 'end', new Date());
}

建议在

onMount
(来自
'svelte'
)中添加事件侦听器,并在销毁时再次清理它:

onMount(() => {
    thisDiv.addEventListener('animationend', doStuff);
    
    () => thisDiv.removeEventListener('animationend', doStuff);
})

REPL

© www.soinside.com 2019 - 2024. All rights reserved.