从概念上讲,使用@html 指令等同于使用el.innerHTML = myHtmlString。
换句话说,在您的 HTML 字符串的上下文中,您完全不在 Svelte 的领域(并且完全在本机浏览器的领域)。
on:click 是特殊的 Svelte 语法,浏览器不会处理它。因此,如果您想要 HTML 字符串中的事件,则需要返回原始 HTML/JS。也就是说,请改用onclick。
当然,onclick 的语义与on:click 的语义完全不同。对于onclick,您只能传递一个字符串,当事件发生时将是eval'd(而对于on:click,您传递一个函数reference,当事件发生)。
为了清楚起见,让我们回顾一下 Svelte 的语法:
<button on:click={doSomething}>Click me</button>
相比之下,在原始 HTML 中,这看起来像:
{@html '<button onclick="doSomething()">Click click!</button>'}
看到重要的区别:使用onclick,您需要调用 doSomething() 函数,否则点击时不会发生任何事情。
现在,更有趣的是:这个doSomething 函数需要在作用域内可用...也就是说,你必须将它附加到window:
<script context="module">
// note: using context=module to avoid adding this function to window
// multiple times
window.doSomething = () => { ... }
</script>
{@html '<button onclick="doSomething()">Click click!</button>'}
这很难看……你可以这样做,以避免污染全局范围:
<script>
import { onMount } from 'svelte'
const doSomething = () => { ... }
onMount(() => {
const btn = document.querySelector('#grab-me')
btn.addEventListener('click', doSomething)
})
</script>
{@html '<button id="grab-me">Click click!</button>'}
现在我们正在污染 DOM id...我们可以通过包装 Svelte 控制的元素来进一步避免这种情况,我们可以使用 bind:this={el} 获取对它的引用...
总而言之,@html 字符串中的动态元素最好避免使用,因为您在其中失去了 Svelte 的所有好处。 @html 最适合呈现静态 HTML 内容。
为什么要将按钮放在字符串中,而不是让 Svelte 管理它?
如果你真的需要走这条路,你可能也对this dirty trick 感兴趣,我绝对不推荐使用它(我永远不会在我自己的代码中使用它)......但这可能会给你进一步了解您想要实现的目标。