Svelte action to inject elements into the DOM
yarn add -D @mibu/svelte-inject
<script>
import {inject} from "@mibu/svelte-inject"
</script>
Useful when injectig Svelte into exising code at runtime, e.g. GreaseMonkey userscripts.
You can already inject Svelte components, but only with one injection point per component:
new App({
target: ..., // Insert into target
anchor: ... // Insert before child of target
});
Consider modifying a webiste by adding a toggle to the navbar and some toggleable content to an existing content container:
<nav id="navbar">
<button id="toggle"/> <!-- toggle we want to inject -->
</nav>
<div id="container">
<div id="content"/> <!-- content we want to inject -->
</div>
You would have to create a component for each and then inject them:
new Toggle({target: document.getElementById("navbar")});
new Content({target: document.getElementById("container")});
But now you are outside the domain of the Svelte compiler and its harder to add reactivity. Lets instead create a App.svelte
component and use the inject
action:
<script>
import inject from "@mibu/svelte-inject"
let showContent = false;
</script>
<button use:inject={"#navbar"} on:click={() => showContent = !showContent}/>
<div use:inject={"#container"} class:hidden={showContent}/>
Now everything is inside one Svelte component and its also reactive.
The inject
action takes one argument {<mode>: <target>}
:
<mode>
: Where the element will be injected<target>
: Either an HTMLElement or a query selector string
<!-- Inject after target -->
<div use:inject={{after: document.getElementById("example")}}>
...
</div>
<!-- Inject before target -->
<div use:inject={{before: "#example"}}>
...
</div>
<!-- Append to target -->
<div use:inject={{append: "li.example"}}>
...
</div>
When you pass just the HTMLElement or a query string, the element will be appended:
<!-- Append to target -->
<div use:inject={document.getElementById("example")}>
...
</div>
<!-- Append to target -->
<div use:inject={"button.active"}>
...
</div>
If you don't pass any arguments, the element will be appended to the body
:
<!-- Append to document.body -->
<div use:inject>
...
</div>