跳至主要内容

[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

這個功能過去需要透過點擊手機瀏覽器上的「分享」後才會出現:

Web Share API

但現在透過 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 亦可:

Web Share API

目前實測在三星內建的瀏覽器上可以使用,但分享成功後的回傳訊息不太正確。

使用方式

使用方式很簡單:

// 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)。

使用時有幾點需留意一下:

  1. Web Share API 只能使用在有 HTTPS 的網站或者是測試時的 localhost,若想玩玩看這個 API 就可以到帶有 HTTPS 的 CodePen 上試試看。
  2. 需要透過使用者主動的行爲(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

  1. 透過 document.querySelector() 選擇和 DOM 有關的元素
  2. 建立使用者點擊分享時要帶入的資訊,不用每一項都填寫,也可以只分享文字或網址
  3. Web Share API 需要使用者主動的行為才能觸發, 所以透過 addEventListener 監聽使用者點擊 click 事件
  4. 透過 navigator.share 來使用 Web Share API
  5. 當使用者拒絕分享或發生錯誤時要顯示的訊息
// 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);
}
}
});

如此就完成這個簡單的範例了。

這個範例的按鈕樣式是修改自 AyooluwaCodePen

來看一下實作的結果:

Web Share API

以 Line 為例,傳送出去的訊息內容如下:

Web Share API

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 文章中提供了非常精緻的替代處理畫面:

Imgur

可以參考這個作者的 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();
}

參考文章