Kurs Svelte i SvelteKit · Moduł 5: Wiązania
Bindings wymiarów i specjalne
W tej lekcji4
Wymiary elementu
<script>
let w = $state(0);
let h = $state(0);
let text = $state('Zmień rozmiar okna!');
</script>
<div
bind:clientWidth={w}
bind:clientHeight={h}
class="box"
>
<p>{text}</p>
<p>Wymiary: {w} x {h}px</p>
</div>
<style>
.box {
width: 100%;
height: 200px;
background: #2a2a4a;
padding: 1rem;
}
</style>Dostępne bindings wymiarów:
clientWidth/clientHeightoffsetWidth/offsetHeight
Scroll
<script>
let scrollY = $state(0);
</script>
<svelte:window bind:scrollY />
<div class="header" class:scrolled={scrollY > 50}>
Viking Saga
</div>
<style>
.header {
position: fixed;
top: 0;
transition: background 0.3s;
}
.header.scrolled {
background: rgba(0, 0, 0, 0.8);
}
</style>Online/Offline status
<script>
let online = $state(true);
</script>
<svelte:window bind:online />
<p>Status: {online ? 'Online' : 'Offline'}</p>Praktyczny przykład: Formularz wikinga
<script>
let warrior = $state({
name: '',
rank: 'drengr',
skills: [],
bio: ''
});
function submit(e) {
e.preventDefault(); // zatrzymaj przeładowanie strony
console.log('Zapisano:', $state.snapshot(warrior));
}
</script>
<form onsubmit={submit}>
<label>
Imię:
<input bind:value={warrior.name} required />
</label>
<label>
Ranga:
<select bind:value={warrior.rank}>
<option value="drengr">Drengr</option>
<option value="jarl">Jarl</option>
</select>
</label>
<fieldset>
<legend>Umiejętności:</legend>
<label>
<input type="checkbox" bind:group={warrior.skills} value="sailing" />
Żeglarstwo
</label>
<label>
<input type="checkbox" bind:group={warrior.skills} value="combat" />
Walka
</label>
</fieldset>
<label>
Biografia:
<textarea bind:value={warrior.bio}></textarea>
</label>
<button type="submit">Zapisz wojownika</button>
</form>Formularz obsługuje atrybut onsubmit, a e.preventDefault() zatrzymuje przeładowanie strony (w Svelte 4 robił to modyfikator |preventDefault). $state.snapshot(warrior) zamienia reaktywny obiekt w zwykłą kopię, czytelną w konsoli.
Kod do tej lekcji: App.svelte
<script>
// DOM bindings - bind:this, bind:clientWidth etc.
// bind:this only needs a plain variable (used in a function, not in the markup)
let inputRef;
// Values shown in the markup must be $state to update the view
let containerWidth = $state(0);
let containerHeight = $state(0);
let scrollY = $state(0);
function focusInput() {
inputRef?.focus();
}
$effect(() => {
console.log('Scroll position:', scrollY);
});
</script>
<svelte:window bind:scrollY />
<main class="dom-demo">
<h1>DOM Bindings</h1>
<section>
<h2>bind:this - element reference</h2>
<input
bind:this={inputRef}
type="text"
placeholder="Click button to focus"
/>
<button onclick={focusInput}>Focus input</button>
</section>
<section bind:clientWidth={containerWidth} bind:clientHeight={containerHeight}>
<h2>bind:clientWidth/Height</h2>
<p>Width: <strong>{Math.round(containerWidth)}px</strong></p>
<p>Height: <strong>{Math.round(containerHeight)}px</strong></p>
<p class="hint">Resize the window to see changes</p>
</section>
<section>
<h2>svelte:window - scroll</h2>
<p>Scroll Y: <strong>{Math.round(scrollY)}px</strong></p>
<div class="scroll-area">
<p>Scroll the page down...</p>
<div class="spacer"></div>
<p>...and observe the scrollY value</p>
</div>
</section>
</main>
<style>
.dom-demo {
font-family: 'Georgia', serif;
max-width: 600px;
margin: 0 auto;
padding: 2rem;
background: #1a0f0a;
color: #e8d5b7;
min-height: 150vh;
}
h1 {
color: #d4af37;
text-align: center;
position: sticky;
top: 0;
background: #1a0f0a;
padding: 1rem 0;
}
section {
background: rgba(212, 175, 55, 0.1);
border: 1px solid #d4af37;
border-radius: 8px;
padding: 1rem;
margin: 1rem 0;
}
h2 {
color: #d4af37;
font-size: 1rem;
margin-top: 0;
}
input {
width: 100%;
padding: 0.75rem;
background: rgba(0,0,0,0.3);
border: 1px solid #3d2914;
border-radius: 4px;
color: #e8d5b7;
margin-bottom: 0.5rem;
}
input:focus {
border-color: #d4af37;
outline: none;
}
button {
padding: 0.5rem 1rem;
background: #3d2914;
color: #e8d5b7;
border: 1px solid #d4af37;
border-radius: 4px;
cursor: pointer;
}
button:hover {
background: #4d3924;
}
strong {
color: #ffd700;
}
.hint {
font-size: 0.85rem;
color: #8b7355;
font-style: italic;
}
.scroll-area {
padding: 1rem;
background: rgba(0,0,0,0.3);
border-radius: 4px;
}
.spacer {
height: 200px;
}
</style>Hasła z dokumentacji w tej lekcji
Widzisz błąd w tej lekcji?
Sprawdź się
Odpowiedz na pytania z tej lekcji. Wybierz odpowiedź, a od razu zobaczysz, czy jest poprawna.
1. Jak śledzić pozycję scrolla okna?