W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗值獎勵
Actions 本質(zhì)上是元素級生命周期函數(shù)。它們在以下方面很有用:
與第三方庫接口
延遲加載圖像
工具提示
添加自定義事件處理程序
在此應(yīng)用程序中,我們希望將橙色框設(shè)置為“pannable”。它具有用于 ?panstart
?、?panmove
? 和 ?panend
? 事件的事件處理程序,但這些不是本機(jī) DOM 事件。我們必須自己調(diào)度他們。首先,導(dǎo)入 ?pannable
? 函數(shù)...
import { pannable } from './pannable.js';
...然后將它與元素一起使用:
<div class="box"
use:pannable
on:panstart={handlePanStart}
on:panmove={handlePanMove}
on:panend={handlePanEnd}
style="transform:
translate({$coords.x}px,{$coords.y}px)
rotate({$coords.x * 0.2}deg)"
></div>
打開 ?pannable.js
? 文件。與 transition 函數(shù)一樣,action 函數(shù)接收一個 ?node
?和一些可選參數(shù),并返回一個動作對象。該對象可以有一個 ?destroy
? 函數(shù),該函數(shù)在元素被卸載時調(diào)用。
我們希望在用戶將鼠標(biāo)放在元素上時觸發(fā) ?panstart
? 事件,在拖動元素時觸發(fā) ?panmove
? 事件(使用 ?dx
? 和 ?dy
? 屬性顯示鼠標(biāo)移動的距離),并在鼠標(biāo)松開時觸發(fā) ?panend
? 事件。一種可能的實(shí)現(xiàn)如下所示:
export function pannable(node) {
let x;
let y;
function handleMousedown(event) {
x = event.clientX;
y = event.clientY;
node.dispatchEvent(new CustomEvent('panstart', {
detail: { x, y }
}));
window.addEventListener('mousemove', handleMousemove);
window.addEventListener('mouseup', handleMouseup);
}
function handleMousemove(event) {
const dx = event.clientX - x;
const dy = event.clientY - y;
x = event.clientX;
y = event.clientY;
node.dispatchEvent(new CustomEvent('panmove', {
detail: { x, y, dx, dy }
}));
}
function handleMouseup(event) {
x = event.clientX;
y = event.clientY;
node.dispatchEvent(new CustomEvent('panend', {
detail: { x, y }
}));
window.removeEventListener('mousemove', handleMousemove);
window.removeEventListener('mouseup', handleMouseup);
}
node.addEventListener('mousedown', handleMousedown);
return {
destroy() {
node.removeEventListener('mousedown', handleMousedown);
}
};
}
更新 ?pannable
? 函數(shù)并嘗試移動盒子。
此實(shí)現(xiàn)僅用于演示目的——更完整的實(shí)現(xiàn)也會考慮觸摸事件。
示例代碼
<script>
import { spring } from 'svelte/motion';
import { pannable } from './pannable.js';
const coords = spring({ x: 0, y: 0 }, {
stiffness: 0.2,
damping: 0.4
});
function handlePanStart() {
coords.stiffness = coords.damping = 1;
}
function handlePanMove(event) {
coords.update($coords => ({
x: $coords.x + event.detail.dx,
y: $coords.y + event.detail.dy
}));
}
function handlePanEnd(event) {
coords.stiffness = 0.2;
coords.damping = 0.4;
coords.set({ x: 0, y: 0 });
}
</script>
<style>
.box {
--width: 100px;
--height: 100px;
position: absolute;
width: var(--width);
height: var(--height);
left: calc(50% - var(--width) / 2);
top: calc(50% - var(--height) / 2);
border-radius: 4px;
background-color: #ff3e00;
cursor: move;
}
</style>
<div class="box"
use:pannable
on:panstart={handlePanStart}
on:panmove={handlePanMove}
on:panend={handlePanEnd}
style="transform:
translate({$coords.x}px,{$coords.y}px)
rotate({$coords.x * 0.2}deg)"
></div>
pannable.js
export function pannable(node) {
let x;
let y;
function handleMousedown(event) {
x = event.clientX;
y = event.clientY;
node.dispatchEvent(new CustomEvent('panstart', {
detail: { x, y }
}));
window.addEventListener('mousemove', handleMousemove);
window.addEventListener('mouseup', handleMouseup);
}
function handleMousemove(event) {
const dx = event.clientX - x;
const dy = event.clientY - y;
x = event.clientX;
y = event.clientY;
node.dispatchEvent(new CustomEvent('panmove', {
detail: { x, y, dx, dy }
}));
}
function handleMouseup(event) {
x = event.clientX;
y = event.clientY;
node.dispatchEvent(new CustomEvent('panend', {
detail: { x, y }
}));
window.removeEventListener('mousemove', handleMousemove);
window.removeEventListener('mouseup', handleMouseup);
}
node.addEventListener('mousedown', handleMousedown);
return {
destroy() {
node.removeEventListener('mousedown', handleMousedown);
}
};
}
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: