我想通过 svelte 中的 html 表达式添加自定义按钮。 通过文档here ,我可以使用 @html 标签来做到这一点。
{@html
`
<button>
click me
</button>
`
}
我现在想向 html 字符串添加一个指令事件处理程序,即单击按钮时将调用的本地定义的函数。到目前为止我尝试过的:
{@html
`
<button
on:click="${()=>doSomething()}">
click me
</button>
`
}
但是,正如我所料,它没有起作用。我想可能还有另一种方法,但到目前为止还没有想到
最佳答案
从概念上讲,使用 @html
指令相当于执行 el.innerHTML = myHtmlString
。
换句话说,在 HTML 字符串的上下文中,您完全超出了 Svelte 的范围(并且完全超出了 native 浏览器的范围)。
on:click
是特殊的 Svelte 语法,浏览器不会处理它。因此,如果您想要 HTML 字符串中的事件,则需要返回原始 HTML/JS。也就是说,使用 onclick
来代替。
当然,onclick
的语义与 on:click
完全不同。对于 onclick
,您只能传递一个字符串,该字符串将在事件发生时进行 eval
处理(而对于 on:click
,您可以传递函数引用,事件发生时将被调用)。
为了更清楚地说明这一点,让我们回顾一下 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 感兴趣。 ,我绝对不建议使用它(我永远不会在我自己的代码中使用它)...但这可能会让您进一步了解您想要实现的目标。
关于javascript - 将事件指令添加到 svelte html 表达式中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60610241/