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小时内与您取得联系。