[WebAPIs] Web Share API 的使用 - navigator.share
keywords: WebAPIs
, mobile
, navigator.share
TL;DR
// 判斷瀏覽器是否支援 Web Share API
if (navigator.share) {
// navigator.share 會回傳 Promise
navigator
.share({
title: 'Web Fundamentals',
text: 'Check out Web Fundamentals — it rocks!',
url: 'https://developers.google.com/web',
})
.then(() => console.log('Successful share'))
.catch((error) => console.log('Error sharing', error));
}
Web Share API 的說明
用手機瀏覽網頁的時候,不知道你有沒有注意過,當你按下分享按鈕時它會跳出一個選單,讓你可以選擇要分享到哪個 App 的選單,像是這樣:
這個功能過去需要透過點擊手機瀏覽器上的「分享」後才會出現:
但現在透過 Web Share 這個 API 也可以輕鬆達到這個功能,讓使用者在點擊網頁上的按鈕後就跳出這個「分享選單」,如此就有機會省去使用那種帶有一堆 Facebook、Line、Twitter、Pinterest 按鈕的第三方套件,進一步減少頁面載入時間。
現在就來看看怎麼使用吧!
Web Share API - navigator.share
適用瀏覽器
Web Share API 的使用方式很簡單,但要注意的是這主要是適用在手機上的功能,畢竟電腦上沒有這種分享選單(目前除了 Mac 的 Safari 可用),不過即使電腦不支援此 API 的使用,還是可以很容易做出替代方案(fallback)。
看到下圖瀏覽器支援性的一大片紅字感覺很恐怖,但目前(2019-11-20)其實主要的手機瀏覽器(Chrome, Safari)都適用,Mac 上的 Safari 亦可:
目前實測在三星內建的瀏覽器上可以使用,但分享成功後的回傳訊息不太正確。
使用方式
使用方式很簡單:
// navigator.share 會回傳一個 Promise
// 下面的欄位可以不用全部填寫,可以只分享網址,也可以只分享文字
const sharePromise = navigator.share({
url: 'https://pjchender.blogspot.com', // 要分享的 URL
title: 'PJCHENder 那些沒告訴你的小細節', // 要分享的標題
text: '好多眉眉角角啊', // 要分享的文字內容
});
navigator.share()
會回傳一個 Promise
(代表你可以搭配 async...await
使用),這個 Promise 會在使用者完成點擊某個 App 分享後被完成(fulfilled);若使用者取消分享或帶入的參數有錯誤時,則會被拒絕(reject)。
使用時有幾點需留意一下:
- Web Share API 只能使用在有 HTTPS 的網站或者是測試時的 localhost,若想玩玩看這個 API 就可以到帶有 HTTPS 的 CodePen 上試試看。
- 需要透過使用者主動的行爲(user activation)才能觸發,例如,點擊事件。
範例程式碼
來看一下範例程式碼吧,也可以直接看 CodePen。
See the Pen Web Share API by PJCHEN (@PJCHENder) on CodePen.
HTML
先建立最基本的一個按鈕:
<div class="center-center">
<button>Share<i class="fas fa-share-alt"></i></button>
<p class="result"></p>
</div>
JavaScript
- 透過
document.querySelector()
選擇 和 DOM 有關的元素 - 建立使用者點擊分享時要帶入的資訊,不用每一項都填寫,也可以只分享文字或網址
- Web Share API 需要使用者主動的行為才能觸發, 所以透過
addEventListener
監聽使用者點擊 click 事件 - 透過
navigator.share
來使用 Web Share API - 當使用者拒絕分享或發生錯誤時要顯示的訊息
// STEP 1:選擇和 DOM 有關的元素
const btn = document.querySelector('button');
const result = document.querySelector('.result');
// STEP 2:建立使用者點擊分享時要帶入的資訊
const shareData = {
url: 'https://pjchender.blogspot.com', // 要分享的 URL
title: 'PJCHENder 那些沒告訴你的小細節', // 要分享的標題
text: '好多眉眉角角啊', // 要分享的文字內容
};
// STEP 3:當使用者點擊按鈕時
btn.addEventListener('click', async () => {
try {
// STEP 4:使用 Web Share API
await navigator.share(shareData);
result.textContent = '感謝你的的分享';
} catch (err) {
// STEP 5:使用者拒絕分享或發生錯誤
const { name, message } = err;
if (name === 'AbortError') {
result.textContent = '您已取消分享此訊息';
} else {
result.textContent = err;
console.log('發生錯誤', err);
}
}
});
如此就完成這個簡單的範例了。
來看一下實作的結果:
以 Line 為例,傳送出去的訊息內容如下:
See the Pen Web Share API by PJCHEN (@PJCHENder) on CodePen.
替代處理與其他(fallback)
對於不支援 Web Share API 的瀏覽器則可以透過判斷 navigator.share
是否存在來進行替代方案:
if (navigator.share) {
// 使用 Web Share API
} else {
// 替代方案寫在這...
}
舉例來說,在 CSS Tricks 的 How to Use the Web Share API 文章中提供了非常精緻的替代處理畫面:
可以參考這個作者的 CodePen 範例。
如果不想這麼複雜的話,替代方案也可以是點擊按鈕後複製網址(Copy Link)給使用者自行分享即可。複製到剪貼簿的方式同樣有對應的 WebAPIs 可以支援,有需要可以參考先前整理的筆記 [WebAPIs] Copy to clipboard 複製到剪貼簿。
範例程式碼:當瀏覽器不支援時讓按鈕變成複製功能
這裡提供實際的範例可以作為參考:
// 選擇和 DOM 有關的元素
const btn = document.querySelector('button');
const result = document.querySelector('.result');
// 當使用者點擊分享時要帶入的資訊
const shareData = {
url: 'https://pjchender.blogspot.com', // 要分享的 URL
title: 'PJCHENder 那些沒告訴你的小細節', // 要分享的標題
text: '好多眉眉角角啊', // 要分享的文字內容
};
btn.addEventListener('click', () => {
// 判斷瀏覽器是否支援 Web Share API
if (navigator.share) {
handleNavigatorShare();
} else {
handleNotSupportNavigatorShare();
}
});
// 當瀏覽器支援 Web Share API 時
async function handleNavigatorShare() {
try {
await navigator.share(shareData);
result.textContent = '感謝你的的分享';
} catch (err) {
// 使用者拒絕分享或發生錯誤
const { name } = err;
if (name === 'AbortError') {
result.textContent = '您已取消分享此訊息';
} else {
result.textContent = err;
console.log('發生錯誤', err);
}
}
}
// 當瀏覽器不支援 Web Share API 時,點下去變成複製
function handleNotSupportNavigatorShare() {
const contentToCopy = document.querySelector('#content-to-copy');
contentToCopy.value = shareData.url;
contentToCopy.setAttribute('type', 'text'); // 不是 hidden 才能複製
contentToCopy.select();
try {
const successful = document.execCommand('copy');
const msg = successful ? '成功' : '失敗';
alert(`${shareData.url} - 複製${msg}`);
} catch (err) {
alert('Oops, unable to copy');
}
/* unselect the range */
contentToCopy.setAttribute('type', 'hidden');
window.getSelection().removeAllRanges();
}
See the Pen Web Share API with Copy Fallback by PJCHEN (@PJCHENder) on CodePen.
參考文章
- How to Use the Web Share API @ CSS Tricks
- Navigator.share @ MDN
- Introducing the Web Share API @ Google Developer
- Registering as a Share Target with the Web Share Target API @ Google Developer