diff --git a/files/ja/web/api/notifications_api/index.md b/files/ja/web/api/notifications_api/index.md index adcf4a871fdcb6..3b8cd40713ca8c 100644 --- a/files/ja/web/api/notifications_api/index.md +++ b/files/ja/web/api/notifications_api/index.md @@ -1,54 +1,56 @@ --- title: 通知 API slug: Web/API/Notifications_API +l10n: + sourceCommit: aa8fa82a902746b0bd97839180fc2b5397088140 --- -{{DefaultAPISidebar("Web Notifications")}}{{AvailableInWorkers}}{{securecontext_header}} +{{DefaultAPISidebar("Web Notifications")}}{{securecontext_header}} {{AvailableInWorkers}} 通知 API を使えば、ウェブページがエンドユーザーに表示するシステム通知を制御できるようになります。これらのシステムは、最上位の閲覧コンテキストのビューポートの外にあるため、ユーザーがタブを切り替えたり、別のアプリに移動していても表示されます。また、この API は既存の通知システムと互換性を持つように設計されているので、異なるプラットフォームでも動作します。 ## 概要と使い方 -対応済みのプラットフォームでは、システム通知を表示するには、一般的に 2 つのことが必要です。まず、ユーザーが現在のオリジンに対してシステム通知を表示する許可を与える必要があります。これは一般的にアプリやサイトが初期化されたとき、 {{domxref("Notification.requestPermission()")}} を使用して行われます。これは、例えばボタンをクリックするなど、ユーザーの操作に反応して行う必要があります。 +対応済みのプラットフォームでは、システム通知を表示するには、一般的に 2 つのことが必要です。まず、ユーザーが現在のオリジンに対してシステム通知を表示する許可を与える必要があります。これは一般的にアプリやサイトが初期化されたとき、 {{domxref("Notification.requestPermission_static", "Notification.requestPermission()")}} メソッドを使用して行われます。 +このメソッドは、例えばユーザーのジェスチャーを処理する場合、マウスクリックを処理する場合などでのみ呼び出すべきです。 ```js -btn.addEventListener("click", function () { +btn.addEventListener("click", () => { let promise = Notification.requestPermission(); // wait for permission }); ``` -これはベストプラクティスで、ユーザーが同意していない通知でユーザーに迷惑をかけるべきではありません。しかし、今後ブラウザーはユーザーの操作から起動されていない通知を明示的に拒否するようになるでしょう。例えば、 Firefox はバージョン 72 からすでにこれを行っています。 - これは以下のようにリクエストダイアログを起動します。 -![](screen_shot_2019-12-11_at_9.59.14_am.png) +![オリジンからの通知を許可するかどうかをユーザーに要求するダイアログボックス。通知を許可しない、または許可するオプションがあります。](screen_shot_2019-12-11_at_9.59.14_am.png) ここでは、ユーザーはこのオリジンからの通知を許可するかどうかを選択できます。一度決定がなされると、現在のセッションの間はその設定が保存されます。 -> [!NOTE] -> Firefox 44 からは、通知と[プッシュ通知](/ja/docs/Web/API/Push_API)の許可が統合されました。通知に許可が与えられれば、プッシュ通知も同時に有効になります。 - -つぎに、新しい通知は {{domxref("Notification.Notification","Notification()")}} コンストラクターを使って作られます。このコンストラクターには、必須の title 引数と、オプションを指定する引数として options オブジェクトを与えることができます。オプションには、テキストの方向、本文テキスト、表示アイコン、通知サウンドなどが指定可能です。 +次に、新しい通知は {{domxref("Notification.Notification","Notification()")}} コンストラクターを使って作られます。このコンストラクターには、必須の title 引数と、オプションを指定する引数として options オブジェクトを与えることができます。オプションには、テキストの方向、本文テキスト、表示アイコン、通知サウンドなどが指定可能です。 さらに、通知 API の仕様には、いくつかの[サービスワーカー API](/ja/docs/Web/API/Service_Worker_API) が定義されており、サービスワーカーが通知を発行できるようになっています。 > [!NOTE] > 自分のアプリでの通知の詳しい使い方については、[通知 API の使用](/ja/docs/Web/API/Notifications_API/Using_the_Notifications_API)を参照してください。 -## 通知インターフェイス +## インターフェイス - {{domxref("Notification")}} - : 通知オブジェクトを定義します。 - -### サービスワーカーの追加要素 - -- {{domxref("ServiceWorkerRegistration")}} - - : {{domxref("ServiceWorkerRegistration.showNotification()")}} および {{domxref("ServiceWorkerRegistration.getNotifications()")}} メソッドが含まれており、通知の表示の制御に使用できます。 -- {{domxref("ServiceWorkerGlobalScope")}} - - : {{domxref("ServiceWorkerGlobalScope.notificationclick_event", "onnotificationclick")}} ハンドラーが含まれており、通知がクリックされた時にカスタム関数を実行させることができるようになります。 - {{domxref("NotificationEvent")}} - - : {{domxref("ExtendableEvent")}} を基本とした、特定の型ののイベントオブジェクトです。すでに実行された通知を表現します。 + - : {{domxref("ServiceWorker")}} の {{domxref("ServiceWorkerGlobalScope")}} に配信された通知イベントを表します。 + +### 他インターフェイスへの拡張 + +- {{domxref("ServiceWorkerGlobalScope/notificationclick_event", "notificationclick")}} イベント + - : 表示された通知をユーザーがクリックすると発生します。 +- {{domxref("ServiceWorkerGlobalScope/notificationclose_event", "notificationclose")}} イベント + - : 表示された通知をユーザーが閉じたときに発生します。 +- {{domxref("ServiceWorkerRegistration.getNotifications()")}} + - : 現在のオリジンから現在のサービスワーカー登録を経由して作成された順番で、通知の一覧を返します。 +- {{domxref("ServiceWorkerRegistration.showNotification()")}} + - : リクエストされたタイトルで通知を表示します。 ## 仕様書 diff --git a/files/ja/web/api/notifications_api/screen_shot_2019-12-11_at_9.59.14_am.png b/files/ja/web/api/notifications_api/screen_shot_2019-12-11_at_9.59.14_am.png new file mode 100644 index 00000000000000..17251c2ec67312 Binary files /dev/null and b/files/ja/web/api/notifications_api/screen_shot_2019-12-11_at_9.59.14_am.png differ diff --git a/files/ja/web/api/notifications_api/using_the_notifications_api/index.md b/files/ja/web/api/notifications_api/using_the_notifications_api/index.md index 08a18a0b0b49b2..13d3e131fd26fe 100644 --- a/files/ja/web/api/notifications_api/using_the_notifications_api/index.md +++ b/files/ja/web/api/notifications_api/using_the_notifications_api/index.md @@ -1,15 +1,17 @@ --- title: 通知 API の使用 slug: Web/API/Notifications_API/Using_the_Notifications_API +l10n: + sourceCommit: aa8fa82a902746b0bd97839180fc2b5397088140 --- -{{APIRef("Web Notifications")}}{{AvailableInWorkers}}{{securecontext_header}} +{{DefaultAPISidebar("Web Notifications")}}{{securecontext_header}} {{AvailableInWorkers}} [通知 API](/ja/docs/Web/API/Notifications_API) は、ウェブページやアプリからシステムレベルでページ外部に表示される通知を送ることを可能にします。これにより、アプリケーションがアイドルやバックグラウンドの状態であっても、アプリからユーザーに情報を送信することができます。この記事では、アプリで API を使用する方法の基本を見ていきます。 一般的にシステム通知とは、オペレーティングシステムの標準的な通知メカニズムを指します。一般的なデスクトップシステムやモバイル端末が、通知を行う方法の実例を思い出しましょう。 -![](android-notification.png) +![デスクトップ通知: To do list via mdn.github.io HEY! Your task "Go shopping" is now overdue](desktop-notification.png) 当然ながらシステム通知の仕組みはプラットフォームやブラウザーによって異なりますが問題はなく、通知 API はほとんどのシステム通知に対して十分な互換性を持つようになっています。 @@ -21,7 +23,7 @@ slug: Web/API/Notifications_API/Using_the_Notifications_API ## 許可の要求 -アプリが通知を送信できるようになる前に、ユーザーはアプリがそれを行う権限を認めなければなりません。これは API がウェブページの外部にあるものと対話しようとする際の一般的な要件です。ユーザは少なくとも 1 回はアプリケーションが通知を送ることを認めなければならず、これによりどのアプリやサイトが通知を表示してよいかをユーザーが制御することができます。 +アプリが通知を送信できるようになる前に、ユーザーはアプリがそれを行う権限を認めなければなりません。これは API がウェブページの外部にあるものと対話しようとする際の一般的な要件です。ユーザーは少なくとも 1 回はアプリケーションが通知を送ることを認めなければならず、これによりどのアプリやサイトが通知を表示してよいかをユーザーが制御することができます。 過去にプッシュ通知が悪用されることがあったため、ウェブブラウザーや開発者はこの問題を緩和するための対策を実装し始めています。通知を表示することの許可を求めるのは、ユーザーの操作 (ボタンをクリックするなど) の反応として行うべきです。ユーザーが同意していない通知でユーザーに迷惑をかけるべきではないので、これはベストプラクティスであるだけでなく、今後ブラウザーはユーザーの操作によって起動されたものではない通知の許可の要求を明示的に拒否するようになるでしょう。例えば、 Firefox はバージョン72からすでにこれを行っており、 Safari もしばらく前からこれを行っています。 @@ -29,7 +31,7 @@ slug: Web/API/Notifications_API/Using_the_Notifications_API ### 現在の許可状態を確認する -読取専用の {{domxref("Notification.permission")}} プロパティの値を調べると、すでに許可を得ているかを確認できます。このプロパティは、3 種類のいずれかの値を取ります。 +読み取り専用の {{domxref("Notification.permission_static", "Notification.permission")}} プロパティの値を調べると、すでに許可を得ているかを確認できます。このプロパティは、3 種類のいずれかの値を取ります。 - `default` - : ユーザーはまだ許可を求められたことがなく、したがって通知は表示されない。 @@ -40,10 +42,10 @@ slug: Web/API/Notifications_API/Using_the_Notifications_API ### 許可を得る -通知を表示する許可をまだ得ていない場合は、アプリケーションは {{domxref("Notification.requestPermission()")}} メソッドを使用してユーザーに要求する必要があります。もっとも簡単な形では、次のようなものがあります。 +通知を表示する許可をまだ得ていない場合は、アプリケーションは {{domxref("Notification.requestPermission_static", "Notification.requestPermission()")}} メソッドを使用してユーザーに要求する必要があります。もっとも簡単な形では、次のようなものがあります。 ```js -Notification.requestPermission().then(function (result) { +Notification.requestPermission().then((result) => { console.log(result); }); ``` @@ -51,11 +53,15 @@ Notification.requestPermission().then(function (result) { これはメソッドのプロミスベースの版を使用しています。古いバージョンに対応したい場合は、次のように古いコールバック版を使用する必要があります。 ```js -Notification.requestPermission(); +Notification.requestPermission((result) => { + console.log(result); +}); ``` コールバック版はオプションで、ユーザーが表示を許可する要求に答えた時に呼び出されるコールバック関数を受け入れます。 +> **メモ:** `Notification.requestPermission` がプロミスベース版に対応しているかどうかを、確実に機能テストする方法はありません。古いブラウザーの対応が必要な場合は、コールバック版を使用してください。非推奨ではありますが、新しいブラウザーでも動作します。詳しくは、[ブラウザー互換性表](/ja/docs/Web/API/Notification/requestPermission_static#ブラウザーの互換性)を参照してください。 + ### 例 To-do リストのデモでは、 "Enable notifications" ボタンを配置し、押されたときにアプリの通知を要求します。 @@ -68,62 +74,23 @@ To-do リストのデモでは、 "Enable notifications" ボタンを配置し ```js function askNotificationPermission() { - // function to actually ask the permissions - function handlePermission(permission) { - // set the button to shown or hidden, depending on what the user answers - if ( - Notification.permission === "denied" || - Notification.permission === "default" - ) { - notificationBtn.style.display = "block"; - } else { - notificationBtn.style.display = "none"; - } - } - - // Let's check if the browser supports notifications + // Check if the browser supports notifications if (!("Notification" in window)) { console.log("This browser does not support notifications."); - } else { - if (checkNotificationPromise()) { - Notification.requestPermission().then((permission) => { - handlePermission(permission); - }); - } else { - Notification.requestPermission(function (permission) { - handlePermission(permission); - }); - } + return; } + Notification.requestPermission().then((permission) => { + // set the button to shown or hidden, depending on what the user answers + notificationBtn.style.display = permission === "granted" ? "none" : "block"; + }); } ``` -最初に 2 番目のメインブロックを見てみると、まず最初に通知に対応しているかどうかチェックしているのが分かります。もし対応していれば、次に `Notification.requestPermission()` のプロミスベース版に対応しているかどうかチェックします。対応している場合は、プロミスベース版 (Safari 以外で対応) を実行し、対応していない場合は古いコールバックベース版 (Safari で対応) を実行します。 - -コードの重複を避けるために、このスニペットの最初のメインブロックである `handlePermission()` 関数の中に、多少のハウスキーピングコードを格納しています。この内部では、 `Notification.permission` の値を明示的に設定し (古いバージョンの Chrome では自動的に設定できないものがありました)、ユーザーが許可ダイアログで選択した内容に応じてボタンを表示・非表示にしています。すでに許可されている場合は表示したくありませんが、ユーザーが許可を拒否することを選択した場合は、後で変更できるようにしたいと考えています。 - -> [!NOTE] -> バージョン 37 より前の Chrome では、 {{domxref("Notification.requestPermission()")}} を `load` イベントのハンドラー内で呼び出すことを許可していませんでした ([issue 274284](https://bugs.chromium.org/p/chromium/issues/detail?id=274284) をご覧ください)。 - -### requestPermission() プロミスの機能検出 - -前に、ブラウザーがプロミス版の `Notification.requestPermission()` に対応しているかどうかをチェックする必要があると言いました。これは以下のようにして行います。 - -```js -function checkNotificationPromise() { - try { - Notification.requestPermission().then(); - } catch (e) { - return false; - } - - return true; -} -``` +最初に 2 番目のメインブロックを見てみると、まず最初に通知に対応しているかどうかチェックしているのが分かります。もしそうであれば、プロミスベース版の `Notification.requestPermission()` を実行し、そうでない場合は、コンソールにメッセージをログ出力します。 -基本的には、 `.then()` メソッドが `requestPermission()` で利用できるかどうかを確認します。成功した場合は `true` を返します。失敗した場合は、 `false` を `catch() {}` ブロック内で返します。 +`then` に渡されるプロミス解決ハンドラー内で、ユーザーが権限ダイアログで選んだ内容に応じてボタンの表示・非表示を切り替えます。すでにその権限が許可されている場合はボタンを表示させたくありませんが、ユーザーが権限を拒否するよう選んだ場合は、後で考えを変えるチャンスを与えるべきです。 -

通知の作成

+## 通知の作成 通知の作成は簡単です。 {{domxref("Notification")}} コンストラクターを使用するだけです。このコンストラクターは通知内に表示するタイトルと、通知を拡張するためのアイコン ({{domxref("Notification.icon","icon")}}) やテキスト本文 ({{domxref("Notification.body","body")}}) などのオプションを受け取ります。 @@ -131,7 +98,7 @@ function checkNotificationPromise() { ```js const img = "/to-do-notifications/img/icon-128.png"; -const text = 'HEY! Your task "' + title + '" is now overdue.'; +const text = `HEY! Your task "${title}" is now overdue.`; const notification = new Notification("To do list", { body: text, icon: img }); ``` @@ -141,7 +108,7 @@ const notification = new Notification("To do list", { body: text, icon: img }); ```js const n = new Notification("My Great Song"); -document.addEventListener("visibilitychange", function () { +document.addEventListener("visibilitychange", () => { if (document.visibilityState === "visible") { // The tab has become visible so clear the now-stale Notification. n.close(); @@ -181,86 +148,84 @@ Notifications API の仕様では、{{domxref("Notification")}} のインスタ 以下の基本的な HTML を想定してください。 ```html - + +
+``` + +```css hidden +#demo-logs { + width: 90%; + height: 100px; + background-color: #ddd; + overflow-x: auto; +} ``` 以下の方法で、複数の通知を扱うことが可能です。 ```js -window.addEventListener("load", function () { - const button = document.getElementsByTagName("button")[0]; - - if (window.self !== window.top) { - // Ensure that if our document is in a frame, we get the user - // to first open it in its own tab or window. Otherwise, it - // won't be able to request permission to send notifications. - button.textContent = "View live result of the example code above"; - button.addEventListener("click", () => window.open(location.href)); - return; - } +const demoLogs = document.querySelector("#demo-logs"); + +window.addEventListener("load", () => { + const button = document.querySelector("#notify"); - button.addEventListener("click", function () { - // If the user agreed to get notified - // Let's try to send ten notifications - if (window.Notification && Notification.permission === "granted") { + button.addEventListener("click", () => { + if (Notification?.permission === "granted") { + demoLogs.innerText += `The site has permission to show notifications. Showing notifications.\n`; + // If the user agreed to get notified + // Let's try to send ten notifications let i = 0; // Using an interval cause some browsers (including Firefox) are blocking notifications if there are too much in a certain time. - const interval = window.setInterval(function () { - // Thanks to the tag, we should only see the "Hi! 9" notification - const n = new Notification("Hi! " + i, { tag: "soManyNotification" }); - if (i++ == 9) { - window.clearInterval(interval); + const interval = setInterval(() => { + // Thanks to the tag, we should only see the "Hi no 9 from MDN." notification + const n = new Notification(`Hi no ${i} from MDN.`, { + tag: "soManyNotification", + }); + if (i === 9) { + clearInterval(interval); } + i++; }, 200); - } - - // If the user hasn't told if they want to be notified or not - // Note: because of Chrome, we are not sure the permission property - // is set, therefore it's unsafe to check for the "default" value. - else if (window.Notification && Notification.permission !== "denied") { - Notification.requestPermission(function (status) { + } else if (Notification && Notification.permission !== "denied") { + demoLogs.innerText += "Requesting notification permission.\n"; + // If the user hasn't told if they want to be notified or not + // Note: because of Chrome, we are not sure the permission property + // is set, therefore it's unsafe to check for the "default" value. + Notification.requestPermission().then((status) => { // If the user said okay if (status === "granted") { + demoLogs.innerText += + "User granted the permission. Sending notifications.\n"; let i = 0; // Using an interval cause some browsers (including Firefox) are blocking notifications if there are too much in a certain time. - const interval = window.setInterval(function () { + const interval = setInterval(() => { // Thanks to the tag, we should only see the "Hi! 9" notification - const n = new Notification("Hi! " + i, { + const n = new Notification(`Message no ${i} from MDN.`, { tag: "soManyNotification", }); - if (i++ == 9) { - window.clearInterval(interval); + if (i === 9) { + clearInterval(interval); } + i++; }, 200); - } - - // Otherwise, we can fallback to a regular modal alert - else { - alert("Hi!"); + } else { + // Otherwise, we can fallback to a regular modal alert + demoLogs.innerText += `User denied the permission request.\n`; } }); - } - - // ユーザが通知を拒否している場合 - else { - // 通常型の alert にフォールバックできます - alert("Hi!"); + } else { + // If the user refuses to get notified, we can fallback to a regular modal alert + demoLogs.innerText += `The site does not have permission to show notifications.\n`; } }); }); ``` -結果は以下のとおりです。 - -{{ EmbedLiveSample('Tag_example', '100%', 30) }} - -## 仕様書 - -{{Specifications}} +### 結果 -## ブラウザーの互換性 +{{ EmbedLiveSample('Tag_example', '100%', 150) }} -{{Compat}} +上記の例をテストするには、ウェブサイト `https://live.mdnplay.dev` の[通知設定](https://support.mozilla.org/en-US/kb/firefox-page-info-window#w_permissions)を変更してください。。 ## 関連情報