velte 中的事件非常直觀且易于使用。 在本指南中,我們將了解如何開始使用 Svelte 事件。 假設您對本指南的 Javascript 有很好的理解。
斯維爾特的活動
當我們在 Svelte 中創建新組件時,我們通常希望它們在用戶與它們交互時執行某些操作——例如,將鼠標懸停在它們上,或單擊它們。 Svelte 允許您通常在 vanilla Javascript 中找到的所有事件。
讓我們從一個基本的例子開始。 下面的組件取自我關于創建 Svelte 組件的文章,并創建了一個簡單的計數器:
<script>
// we write export let to say that this is a property
// that means we can change it later!
let x = 0;
const addToCounter = function() {
++x;
}
</script><button id="counter">{x}</button>
每次用戶單擊按鈕時,我們希望 addToCounter 觸發,這會將 x 增加 1,并將其顯示在按鈕本身內。為此,我們添加了一個事件。這是用戶單擊按鈕時我們需要添加的事件:
<button id="counter" on:click={addToCounter}>{x}</button>
我們在 Svelte 中使用 {} 表示該屬性的值是 Javascript。任何有效的 Javascript 事件都可以用來代替點擊。例如,每當鼠標移到按鈕上時,下面的代碼都會增加計數器:
<button id="counter" on:mouseover={addToCounter}>{x}</button>
類似地,您可以使用其他 Javascript 事件,如單擊、滾動、懸停、mouseup、pointerup、pointerdown、mousedown 等。這些只是示例 - 但可以使用您想要使用的任何 Javascript 事件。
在 Svelte 事件中訪問事件數據
有時,我們希望在用戶與我們的組件交互時訪問 e 或事件數據。事件對象攜帶了很多關于觸發事件的有用信息。為此,我們只需將處理程序更改為函數。
例如,讓我們檢索按鈕的單擊位置,并將其顯示給用戶。
<script>
// we write export let to say that this is a property
// that means we can change it later!
let x = 0;
let click = [0, 0] const addToCounter = function(e) {
click[0] = e.clientX;
click[1] = e.clientY;
++x;
}
</script><button id="counter" on:click={(e) => { addToCounter(e) }}>
Clicked {x} times, last at {click[0]}, {click[1]}
</button>
在這里,我們將 e.clientX 和 e.clientY 存儲在一個變量中,并在單擊按鈕時將其顯示給用戶。 對于那些不知道的人,e.clientX 和 e.clientY 都指的是觸發事件時光標位置的一個方面。 Svelte 天生具有反應性,因此無論何時單擊該按鈕都會使用最新數據自動更新。
Svelte 事件轉發
事件轉發是每當用戶觸發子組件上的事件時,我們希望在父組件中處理該事件。 它本質上是說這個組件可以有一個特定的事件,但這里不做處理。 查看我們之前的示例,我們可以通過設置可以在子組件上轉發的事件來首先設置事件轉發。 假設我們在名為 Comp.svelte 的文件中創建了一個組件,該文件如下所示。 一個按鈕是可點擊的,而另一個是不可點擊的。
<button on:click>
Click me, I am a button
</button>
<button>
I am unclickable. Ignore me.
</button>
這里我們說第一個按鈕有一個有效的 on:click 事件。 這很有用,因為它允許我們在組件中定義某些元素,其中包含可以向上轉發的有效事件。 然后,在我們的父級中,我們可以導入我們的按鈕,如下所示:
<script>
import Comp from './Comp.svelte'; let x = 0;
const addToCounter = () => {
++x;
}
</script><Comp on:click={addToCounter} />
現在,當用戶單擊 Comp 中的第一個按鈕時,它將觸發 on:click 事件并運行 addToCounter 函數。 如果我們從 Comp.svelte 中完全刪除 on:click,那么盡管在 Comp 組件上定義了 on:click,但不會觸發任何事件。 這意味著我們不僅可以定義子組件應該附加一個事件,而且我們還可以通過將其添加到子組件本身來定義哪些特定元素具有該事件。 這給了我們很大的靈活性。
最后的想法
Svelte 事件使用起來很簡單,而且它們遵循與原生 Javascript 事件相同的命名約定,這使得它們使用起來非常簡單。 在本指南中,我們介紹了基礎知識,因此您可以開始使用。
函數防抖是頻繁發生的情況下,當有足夠的空閑時間,才會執行代碼一次,是優化高頻率執行代碼的一種手段。實際開發中會遇到頻發觸發事件的情況,比如
resize, scroll, mousemove事件。
原理
事件觸發 n 秒后執行,如果在這 n 秒內再次觸發,則以新的事件時間為準,n 秒后執行。無論觸發多少次,都要等到最后一次觸發 n 秒后才執行。
實現
用 mousemove舉例,當鼠標移入時,在 div 內顯示事件函數執行的次數。防抖的簡單實現如下:
<div id='container'></div>
let count = 0;let oDiv = document.querySelector('#container');//防抖函數function debounce(fn, delay) { let timer; return function() { clearTimeout(timer); timer = setTimeout(fn, delay); } }//事件函數function eventFn() { oDiv.innerHTML = ++count; } oDiv.onmousemove = debounce(eventFn, 1000);
this指向
正常情況下,在事件函數中使用 this指向該事件綁定的元素。而此時 eventFn是作為定時器的一個參數,this指向 window,需要更正 this指向。
function debounce(fn, delay) { let timer; return function() { let _this = this; clearTimeout(timer); timer = setTimeout(function () { fn.apply(_this); }, delay); } }
event對象
一般情況下,事件函數 eventFn的第一個參數為 event對象,但此時,值為 undefined。修改防抖函數:
function debounce(fn, delay) { let timer; return function() { let _this = this; let opt = arguments; clearTimeout(timer); timer = setTimeout(function () { fn.apply(_this, arguments); }, delay); } }
立即執行
防抖函數中使用了定時器,事件觸發后會延遲一定時間才調用事件函數,有時我們希望觸發事件可以立即執行,然后需要 n 秒后才能重新觸發執行。我們通過傳入第三個參數,判斷是否需要立即執行。
者:伯樂在線/chokcoco
http://web.jobbole.com/95068/
何為滾動視差
視差滾動(Parallax Scrolling)是指讓多層背景以不同的速度移動,形成立體的運動效果,帶來非常出色的視覺體驗。 作為網頁設計的熱點趨勢,越來越多的網站應用了這項技術。
通常而言,滾動視差在前端需要輔助 Javascript 才能實現。當然,其實 CSS 在實現滾動視差效果方面,也有著不俗的能力。下面就讓我們來見識一二:
認識 background-attachment
background-attachment 算是一個比較生僻的屬性,基本上平時寫業務樣式都用不到這個屬性。但是它本身很有意思。
background-attachment:如果指定了 background-image ,那么 background-attachment 決定背景是在視口中固定的還是隨著包含它的區塊滾動的。
單單從定義上有點難以理解,隨下面幾個 Demo 了解下 background-attachment 到底是什么意思:
background-attachment: scroll
scroll 此關鍵字表示背景相對于元素本身固定, 而不是隨著它的內容滾動。
background-attachment: local
local 此關鍵字表示背景相對于元素的內容固定。如果一個元素擁有滾動機制,背景將會隨著元素的內容滾動, 并且背景的繪制區域和定位區域是相對于可滾動的區域而不是包含他們的邊框。
background-attachment: fixed
fixed 此關鍵字表示背景相對于視口固定。即使一個元素擁有滾動機制,背景也不會隨著元素的內容滾動。
注意一下 scroll 與 fixed,一個是相對元素本身固定,一個是相對視口固定,有點類似 position 定位的 absolute 和 fixed。
可以感受下 3 種不同取值的不同效果:
CodePen Demo — bg-attachment Demo(https://codepen.io/Chokcoco/pen/xJJorg)
使用 background-attachment: fixed 實現滾動視差
首先,我們使用 background-attachment: fixed 來實現滾動視差。fixed 此關鍵字表示背景相對于視口固定。即使一個元素擁有滾動機制,背景也不會隨著元素的內容滾動。
這里的關鍵在于,即使一個元素擁有滾動機制,背景也不會隨著元素的內容滾動。也就是說,背景圖從一開始就已經被固定死在初始所在的位置。
我們使用,圖文混合排布的方式,實現滾動視差,HTML 結構如下,.g-word 表示內容結構,.g-img 表示背景圖片結構:
<section class="g-word">Header</section>
<section class="g-img">IMG1</section>
<section class="g-word">Content1</section>
<section class="g-img">IMG2</section>
<section class="g-word">Content2</section>
<section class="g-img">IMG3</section>
<section class="g-word">Footer</section>
關鍵 CSS:
section {
height: 100vh;
}
.g-img {
background-image: url(...);
background-attachment: fixed;
background-size: cover;
background-position: center center;
}
效果如下:
CodePen Demo — https://codepen.io/Chokcoco/pen/JBaQoY(https://codepen.io/Chokcoco/pen/JBaQoY)
嗯?有點神奇,為什么會是這樣呢?可能很多人會和我一樣,第一次接觸這個屬性對這樣的效果感到懵逼。
我們把上面 background-attachment: fixed 注釋掉,或者改為 background-attachment: local,再看看效果:
CodePen Demo — bg-attachment:local(https://codepen.io/Chokcoco/pen/ZjMdJz)
這次,圖片正常跟隨滾動條滾動了,按常理,這種效果才符合我們大腦的思維。
而滾動視差效果,正是不按常理出牌的一個效果,重點來了:
當頁面滾動到圖片應該出現的位置,被設置了 background-attachment: fixed 的圖片并不會繼續跟隨頁面的滾動而跟隨上下移動,而是相對于視口固定死了。
好,我們再來試一下,如果把所有 .g-word 內容區塊都去掉,只剩下全部設置了 background-attachment: fixed 的背景圖區塊,會是怎么樣呢?
HTML 代碼如下:
<section class="g-img">IMG1</section>
<section class="g-img">IMG2</section>
<section class="g-img">IMG3</section>
section {
height: 100vh;
}
.g-img {
background-image: url(...);
background-attachment: fixed;
background-size: cover;
background-position: center center;
}
效果如下:
CodePen Demo(https://codepen.io/Chokcoco/pen/oMPrGZ)
結合這張 GIF,相信能對 background-attachment: fixed 有個更深刻的認識,移動的只有視口,而背景圖是一直固定死的。
綜上,就是 CSS 使用 background-attachment: fixed 實現滾動視差的一種方式,也是相對而言比較容易的一種。當然,background-attachment: fixed 本身的效果并不僅只是能有用來實現滾動視差效果,合理運用,還可以實現其他很多有趣的效果,這里簡單再列一個:
background-attachment: fixed 實現圖片點擊水紋效果
利用圖片相對視口固定,可以有很多有趣的效果,譬如下面這個,來源于這篇文章CSS Water Wave (水波效果):
CodePen Demo — bg-attachment:fixed Wave(https://codepen.io/Chokcoco/pen/wxYZWO)
利用圖片相對視口固定的特性實現點擊的水紋效果。
上面這個效果有點瑕疵,圖片在放大容器變大的過程中發生了明顯的抖動。當然,效果還是可以的,background-attachment 還有很多有意思的效果可以挖掘。
使用 transform: translate3d 實現滾動視差
言歸正傳,下面介紹另外一種使用 CSS 實現的滾動視差效果,利用的是 CSS 3D。
原理就是:
關于 transform-style: preserve-3d 以及 perspective 本文不做過多篇幅展開,默認讀者都有所了解,還不是特別清楚的,可以先了解下 CSS 3D。
核心代碼表示就是:
<div class="g-container">
<div class="section-one">translateZ(-1)</div>
<div class="section-two">translateZ(-2)</div>
<div class="section-three">translateZ(-3)</div>
</div>
html {
height: 100%;
overflow: hidden;
}
body {
perspective: 1px;
transform-style: preserve-3d;
height: 100%;
overflow-y: scroll;
overflow-x: hidden;
}
.g-container {
height: 150%;
.section-one {
transform: translateZ(-1px);
}
.section-two {
transform: translateZ(-2px);
}
.section-three {
transform: translateZ(-3px);
}
}
總結就是父元素設置 transform-style: preserve-3d 和 perspective: 1px,子元素設置不同的 transform: translateZ,滾動滾動條,效果如下:
CodePen Demo — CSS 3D parallax(https://codepen.io/Chokcoco/pen/EpOeRm)
很明顯,當滾動滾動條時,不同子元素的位移程度從視覺上看是不一樣的,也就達到了所謂的滾動視差效果。
滾動視差文字陰影/虛影效果
那么,運用 translate3d 的視差效果,又能有一些什么好玩的效果呢?下面這個滾動視差文字陰影/虛影效果很有意思:
CodePen Demo — CSS translate3d Parallax(https://codepen.io/Chokcoco/pen/XBgBBp)
當然,通過調整參數(perspective: ?px 以及 transform: translateZ(-?px);),還能有其他很有意思的效果出現:
CodePen Demo — CSS translate3d Parallax 2(https://codepen.io/Chokcoco/pen/PBXwdX)
是不是很有電影開片的廠商 LOGO 的特效的感覺 joy 。
師父領進門,修行在個人,怎么制作更好更有意思的效果還是需要花時間鉆研和琢磨,這里我僅僅是拋磚引玉,希望能見到更多 Nice 的效果。
好了,本文到此結束,希望對你有幫助 :)
*請認真填寫需求信息,我們會在24小時內與您取得聯系。