You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
svelte/site/content/guide/06-special-components.md

136 lines
3.3 KiB

---
title: Special elements
---
Svelte includes a handful of built-in elements with special behaviour.
### `<svelte:self>`
Sometimes, a component needs to embed itself recursively — for example if you have a tree-like data structure. In Svelte, that's accomplished with the `<svelte:self>` tag:
```html
<!-- { title: '<svelte:self> tags' } -->
{#if countdown > 0}
<p>{countdown}</p>
<svelte:self countdown="{countdown - 1}"/>
{:else}
<p>liftoff!</p>
{/if}
```
```json
/* { hidden: true } */
{
countdown: 5
}
```
### `<svelte:component>`
If you don't know what kind of component to render until the app runs — in other words, it's driven by state (aka a dynamic component) — you can use `<svelte:component>`:
```html
<!-- { title: '<svelte:component> tags' } -->
<script>
import Red from './Red.html';
import Blue from './Blue.html';
let foo = true;
</script>
<input type=checkbox bind:checked={foo}> foo
<svelte:component this="{foo ? Red : Blue}" name="thing"/>
```
```html
<!--{ hidden: true, filename: 'Red.html' }-->
<p style="color: red">Red {name}</p>
```
```html
<!--{ hidden: true, filename: 'Blue.html' }-->
<p style="color: blue">Blue {name}</p>
```
The expression inside the `this="{...}"` can be any valid JavaScript expression.
### `<svelte:window>`
The `<svelte:window>` tag gives you a convenient way to declaratively add event listeners to `window`. Event listeners are automatically removed when the component is destroyed.
```html
<!-- { title: '<svelte:window> tags' } -->
<svelte:window on:keydown="{e => (key = event.key, keyCode = e.keyCode)}"/>
<style>
kbd {
background-color: #eee;
border: 2px solid #f4f4f4;
border-right-color: #ddd;
border-bottom-color: #ddd;
font-size: 2em;
margin: 0 0.5em 0 0;
padding: 0.5em 0.8em;
font-family: Inconsolata;
}
</style>
{#if key}
<p><kbd>{key === ' ' ? 'Space' : key}</kbd> (code {keyCode})</p>
{:else}
<p>click in this window and press any key</p>
{/if}
```
You can also bind to certain values — so far `innerWidth`, `outerWidth`, `innerHeight`, `outerHeight`, `scrollX`, `scrollY` and `online`:
```html
<!-- { title: '<svelte:window> bindings' } -->
<svelte:window bind:scrollY={y}/>
<style>
.background {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 9999px;
background: linear-gradient(to bottom, #7db9e8 0%,#0a1d33 100%);
}
.fixed {
position: fixed;
top: 1em;
left: 1em;
color: white;
}
</style>
<div class="background"></div>
<p class="fixed">user has scrolled {y} pixels</p>
```
### `<svelte:body>`
The `<svelte:body>` tag, just like `<svelte:window>`, gives you a convenient way to declaratively add event listeners to the `document.body` object. This is useful for listening to events that don't fire on `window`, such as `mouseenter` and `mouseleave`.
### `<svelte:head>`
If you're building an application with Svelte — particularly if you're using [Sapper](https://sapper.svelte.technology) — then it's likely you'll need to add some content to the `<head>` of your page, such as adding a `<title>` element.
You can do that with the `<svelte:head>` tag:
```html
<!-- { title: '<svelte:head> tags' } -->
<svelte:head>
<title>{post.title} • My blog</title>
</svelte:head>
```
When [server rendering](docs#server-side-rendering), the `<head>` contents can be extracted separately to the rest of the markup.