Day 29 | 很像 Vue 的 AlpineJS(四): x-on

x-on

x-on 可以简单的用从 DOM 中来触发事件,像是最常用的按钮:

<button x-on:click="alert('Hello World!')">Say Hi</button>

缩写

跟 Vue 一样都能够把 x-on:click 缩写成 @click,像是上面的范例就可以写成这样:

<button @click="alert('Hello World!')">Say Hi</button>

事件物件

如果有需要用到 JavaScritp 的原生事件,可以透过 AlpineJS 的魔术方法 $event 来取得:

范例会取得写在 <button> 中的 message 属性的值,因此会印出 「Hello World」

<button @click="alert($event.target.getAttribute('message'))" message="Hello World">Say Hi</button>

也可以写成这样

<button @click="handleClick">...</button>
 
<script>
    function handleClick(e) {
        // Now you can access the event object (e) directly
    }
</script>

或是

<button @click="e => console.log(e)">...</button>

键盘输入事件

AlpineJS 也能在键盘 keydownkeyup时触发事件:

范例为按下 enter 後触发事件

<input type="text" @keyup.enter="alert('Submitted!')">

同时按下多个按键

如果有需要同时按两个键才触发,就可以这样写:

必须同时按下 shift + enter 才会触发

<input type="text" @keyup.shift.enter="alert('Submitted!')">

或是更多 shift + enter + a

<input type="text" @keyup.shift.a.enter="alert('Submitted!')">

基本上所有按键都能拿来当触发条件,但同时绑多个可能多尝试一下顺序排列。如果要找更多按键的名称可以参考 MDN KeyboardEvent.key

自定义事件

AlpineJS 的监听器是包装後的原生监听器,因此可以接收来自任何 DOM 的事件或是自定义的事件:

<div x-data @foo="alert('Button Was Clicked!')">
    <button @click="$event.target.dispatchEvent(new CustomEvent('foo', { bubbles: true }))">...</button>
</div>

或是更简单的写法,透过魔术方法 $dispatch

<div x-data @foo="alert('Button Was Clicked!')">
  <button @click="$dispatch('foo')">...</button>
</div>

修饰符

.prevent

<form @submit.prevent="console.log('submitted')" action="/foo">
    <button>Submit</button>
</form>

正常情况下当 submit 的时候会触发 action 将表单的内容提交到 /foo。如果使用了 @submit.prevent 就只会执行 @submit 里面写的指令,而不是像原本一样转跳至 /foo


.stop

会阻止外层的事件执行,像是:

由於里面使用了 @click.stop 因此外层的 @click 就不会执行了。

<div @click="console.log('I will not get logged')">
    <button @click.stop>Click Me</button>
</div>

.outside

可以监听该元素以外的点击事件。

注意:

  1. 会监听该元素以外的事件,意味着点击该元素则不会触发 @click
  2. 对整个画面都有效,即便点击的地方在 x-data 所包含的区块外
<div class="shadow-lg w-96 p-5" >
    <div  @click.outside="console.log('click!!')">按钮</div>
</div>

.window

使用後该 @click 将会监听整个 window物件 而不是原本的标签。

像是在画面上按下 ESC 则会触发该事件

<div @keyup.escape.window="...">...</div>

.document

如同上面的 .window,只是变成监听整个 document


.debounce

与昨天的很像,会在触发後某段时间内没有再次被触发才会生效,预设为250ms。可以有效防止短时间过快的触发,尤其是在 @input 上。且一样可以自行设置 debounce 的时间。

简单来说,预设情况下,在不断输入文字的同时至少要停止输入超过250ms,才会触发 @input 事件。

<input @input.debounce.1000ms="doSomething">

.throttle

简单来说,就是会在触发後冷却某段时间才会在触发,预设 250ms。

官方文件举一个很好的例子:在监听卷轴滑动时,通常滑一下都会触发超级多个事件,而我们根本不需要那麽频繁的触发。透过 .throttle 就可以在某特定时间内才触发一次就好,像是预设的话每隔 250ms 才会执行一次自订的滑动卷轴事件。

<div @scroll.window.throttle="handleScroll">...</div>

.self

可以确定是点在自己这个元素本身,而不是被本身包含的字元素。

范例中必须点击 div 的区块才会有作用,如果点到里面的 button 的话也不会触发写在 div 上的 @click

<div @click.self="alert('click')">
    <button>按钮</button>
</div>

<<:  JavaScript Arguments and Spread

>>:  反馈与「大便三明治」

Day 02 - 行前说明 — 网页微切版架构 和 UI 元件

作为正式开始的第一篇要来讲的是很基础的网页切版和怎麽去看网页中有哪些元件,会分两部分: 网页微切版...

30天学会 Python: Day 7-无限轮回

range(start=0, stop, step=1) 用来产生 整数等差数列 的函式,常和今天要...

Day27-更改UIButton的Image大小,代志不是你想的这麽简单

上一篇提到设置了一个Sign In With Apple的按钮,是使用UIButton里面的Imag...

Angular 深入浅出三十天:表单与测试 Day11 - Reactive Forms 实作 - 动态表单初体验

今天要来用 Reactive Forms 的方式再来实作一次昨天的表单。 具体的规格需求跟昨天差不...

【Day 30】第12届iT邦帮忙铁人赛 - 完赛笔记

最近依旧忙录,但工作的需要,我还是需要了解新的技术,努力排出时间用在技术研读上,评估一些技术引进的议...