有些網頁會在右側出現小視窗,事實上這是 HTML 5 所提供 Notification,由 Browser 所提供,可直接使用。
Version
HTML 5
Notification
詢問 user 是否允許 notification。
<template>
<div>HTML Notification</div>
</template>
<script>
let supportNotification = () => ('Notification' in window)
let mounted = async function() {
if (!supportNotification()) return
let permission = await Notification.requestPermission()
if (permission === 'granted')
return new Notification('Sam', { body: 'Hello World' })
}
export default {
mounted
}
</script>
第 6 行
let supportNotification = () => ('Notification' in window)
若 browser 有支援 notification,則 window
Object 會有 Notification
property,因此可自行設計 supportNotification()
判斷 browser 是否支援。
11 行
let permission = await Notification.requestPermission()
if (permission === 'granted')
return new Notification('Sam', { body: 'Hello World' })
若要使用 notification,首先必須使用 Notification.requestPermission()
取得 user 的允許,其回傳為 Promise,可傳入 callback 取得 permission。
default
:還未取得 permissiongranted
:user 允許使用 notificationdenied
:user 拒絕使用 notification
由 Notification
constructor 建立 notification:
Sam
:為 title 部分{ body: 'Hello World' }
:為 body 部分
Promise Chain
<template>
<div>HTML Notification</div>
</template>
<script>
let supportNotification = () => ('Notification' in window)
let mounted = function() {
if (!supportNotification()) return
Notification
.requestPermission()
.then(x => {
if (x === 'granted')
return new Notification('Sam', { body: 'Hello World' })
})
}
export default {
mounted
}
</script>
11 行
Notification
.requestPermission()
.then(x => {
if (x === 'granted')
return new Notification('Sam', { body: 'Hello World' })
})
也可使用 Promise Chain 在 then()
的 callback 中判斷。
<template>
<div>HTML Notification</div>
</template>
<script>
let supportNotification = () => ('Notification' in window)
let mounted = function() {
if (!supportNotification()) return
Notification
.requestPermission()
.then(x => x === 'granted')
.then(x => x && new Notification('Sam', { body: 'Hello World' }))
}
export default {
mounted
}
</script>
11 行
Notification
.requestPermission()
.then(x => x === 'granted')
.then(x => x && new Notification('Sam', { body: 'Hello World' }))
也可使用多個 then()
讓 Promise Chain 好看些。
Function Pipeline
<template>
<div>HTML Notification</div>
</template>
<script>
import { pipe, bind, andThen as then, equals, when } from 'ramda'
let supportNotification = () => ('Notification' in window)
let requestPermission = bind(Notification.requestPermission, Notification)
let createNotification = (title, options) => new Notification(title, { body: options })
let mounted = function() {
if (!supportNotification()) return
pipe(
requestPermission,
then(equals('granted')),
then(when(equals(true), createNotification('Sam', 'Hello World')))
)()
}
export default {
mounted
}
</script>
10 行
let requestPermission = bind(Notification.requestPermission, Notification)
使用 bind()
從 Notification.requestPermission()
抽出 requestPermission()
free function。
12 行
let createNotification = (title, options) => new Notification(title, { body: options })
使用 createNotification()
建立 Notification
Object。
17 行
pipe(
requestPermission,
then(equals('granted')),
then(when(equals(true), createNotification('Sam', 'Hello World')))
)()
在 pipe()
中使用 Promise Chain。
<template>
<div>HTML Notification</div>
</template>
<script>
import { pipe, bind, andThen as then, equals } from 'ramda'
import { iif } from 'wink-fp'
let supportNotification = () => ('Notification' in window)
let requestPermission = bind(Notification.requestPermission, Notification)
let createNotification = (title, options) => pipe(
equals('granted'),
iif(() => new Notification(title, { body: options }))
)
let mounted = pipe(
supportNotification,
iif(requestPermission),
then(createNotification('Sam', 'Hello World'))
)
export default {
mounted
}
</script>
13 行
let createNotification = (title, options) => pipe(
equals('granted'),
iif(() => new Notification(title, { body: options }))
)
也可使用 Wink-fp 的 iif()
取代 when(equals(true))
,可讀性更高。
18 行
let mounted = pipe(
supportNotification,
iif(requestPermission),
then(createNotification('Sam', 'Hello World'))
)
直接使用 pipe()
組合出 mounted()
。
Conclusion
- 若只要學習如何使用 HTML 5 的 notification api,看到
async await
即可,後面是用Notification.requestPermission()
回傳Promise
特性繼續重構 - 若使用
async await
,由於其 Imperative 特性,可發現重構到一個階段就停止了;但若使用then()
,由於其 Function Pipeline 本質,可繼續重構改用pipe()
Reference
MDN, Using the Notification API
Ben Kennish, HTML 5 Web Notification Test