اولاً بابت آن عنوان افتضاح عذرخواهی می کنم، اما نتوانستم.
در Chrome 44 Notfication.data و ServiceWorkerRegistration.getNotifications() اضافه شدهاند و برخی از موارد استفاده رایج را در هنگام برخورد با اعلانها با پیامهای فشاری باز میکنند/ ساده میکنند.
داده های اطلاع رسانی
Notification.data به شما امکان می دهد یک شی جاوا اسکریپت را با یک Notification مرتبط کنید.
آنچه که اساساً به آن خلاصه می شود، این است که وقتی یک پیام فشار دریافت می کنید، می توانید یک اعلان با مقداری داده ایجاد کنید، سپس در رویداد notificationclick می توانید اعلانی را که کلیک شده است دریافت کنید و داده های آن را دریافت کنید.
به عنوان مثال، ایجاد یک آبجکت داده و افزودن آن به گزینه های اعلان مانند این موارد:
self.addEventListener('push', function(event) {
console.log('Received a push message', event);
var title = 'Yay a message.';
var body = 'We have received a push message.';
var icon = '/images/icon-192x192.png';
var tag = 'simple-push-demo-notification-tag';
var data = {
doge: {
wow: 'such amaze notification data'
}
};
event.waitUntil(
self.registration.showNotification(title, {
body: body,
icon: icon,
tag: tag,
data: data
})
);
});
به این معنی که می توانیم اطلاعات را در رویداد notificationclick دریافت کنیم:
self.addEventListener('notificationclick', function(event) {
var doge = event.notification.data.doge;
console.log(doge.wow);
});
قبل از این، باید دادهها را در IndexDB ذخیره میکردید یا چیزی را در انتهای URL نماد - eek قرار میدادید.
ServiceWorkerRegistration.getNotifications()
یکی از درخواستهای رایج توسعهدهندگانی که روی اعلانهای فشاری کار میکنند، کنترل بهتری بر اعلانهایی است که نمایش میدهند.
یک مثال استفاده از یک برنامه چت است که در آن کاربر چندین پیام ارسال می کند و گیرنده اعلان های متعددی را نمایش می دهد. در حالت ایدهآل، برنامه وب میتواند متوجه شود که چندین اعلان دارید که مشاهده نشدهاند و آنها را در یک اعلان جمع میکند.
بدون getNotifications() بهترین کاری که می توانید انجام دهید این است که اعلان قبلی را با آخرین پیام جایگزین کنید. با getNotifications()، میتوانید اعلانها را در صورتی که اعلانهایی از قبل نمایش داده شده است، «جمع کنید» - که منجر به تجربه کاربری بسیار بهتری میشود.
کد انجام این کار نسبتاً ساده است. در داخل رویداد فشار خود، با ServiceWorkerRegistration.getNotifications() تماس بگیرید تا آرایهای از اعلانهای فعلی را دریافت کنید و از آنجا رفتار مناسب را تصمیم بگیرید، خواه این رفتار همه اعلانها را جمع کند یا با استفاده از Notification.tag.
function showNotification(title, body, icon, data) {
var notificationOptions = {
body: body,
icon: icon ? icon : 'images/touch/chrome-touch-icon-192x192.png',
tag: 'simple-push-demo-notification',
data: data
};
self.registration.showNotification(title, notificationOptions);
return;
}
self.addEventListener('push', function(event) {
console.log('Received a push message', event);
// Since this is no payload data with the first version
// of Push notifications, here we'll grab some data from
// an API and use it to populate a notification
event.waitUntil(
fetch(API_ENDPOINT).then(function(response) {
if (response.status !== 200) {
console.log('Looks like there was a problem. Status Code: ' +
response.status);
// Throw an error so the promise is rejected and catch() is executed
throw new Error();
}
// Examine the text in the response
return response.json().then(function(data) {
var title = 'You have a new message';
var message = data.message;
var icon = 'images/notification-icon.png';
var notificationTag = 'chat-message';
var notificationFilter = {
tag: notificationTag
};
return self.registration.getNotifications(notificationFilter)
.then(function(notifications) {
if (notifications && notifications.length > 0) {
// Start with one to account for the new notification
// we are adding
var notificationCount = 1;
for (var i = 0; i < notifications.length; i++) {
var existingNotification = notifications[i];
if (existingNotification.data &&
existingNotification.data.notificationCount) {
notificationCount +=
existingNotification.data.notificationCount;
} else {
notificationCount++;
}
existingNotification.close();
}
message = 'You have ' + notificationCount +
' weather updates.';
notificationData.notificationCount = notificationCount;
}
return showNotification(title, message, icon, notificationData);
});
});
}).catch(function(err) {
console.error('Unable to retrieve data', err);
var title = 'An error occurred';
var message = 'We were unable to get the information for this ' +
'push message';
return showNotification(title, message);
})
);
});
self.addEventListener('notificationclick', function(event) {
console.log('On notification click: ', event);
if (Notification.prototype.hasOwnProperty('data')) {
console.log('Using Data');
var url = event.notification.data.url;
event.waitUntil(clients.openWindow(url));
} else {
event.waitUntil(getIdb().get(KEY_VALUE_STORE_NAME,
event.notification.tag).then(function(url) {
// At the moment you cannot open third party URL's, a simple trick
// is to redirect to the desired URL from a URL on your domain
var redirectUrl = '/redirect.html?redirect=' +
url;
return clients.openWindow(redirectUrl);
}));
}
});
اولین چیزی که با این قطعه کد برجسته می شود این است که ما اعلان های خود را با ارسال یک شی فیلتر به getNotifications() فیلتر می کنیم. این بدان معنی است که ما می توانیم لیستی از اعلان ها را برای یک برچسب خاص (در این مثال برای یک مکالمه خاص) دریافت کنیم.
var notificationFilter = {
tag: notificationTag
};
return self.registration.getNotifications(notificationFilter)
سپس به اعلانهایی که قابل مشاهده هستند نگاه میکنیم و بررسی میکنیم که آیا تعداد اعلانها مرتبط با آن اعلان و بر اساس آن افزایش مییابد. به این ترتیب، اگر یک اعلان به کاربر بگوید که دو پیام خوانده نشده وجود دارد، میخواهیم به این نکته اشاره کنیم که وقتی یک فشار جدید میرسد، سه پیام خوانده نشده وجود دارد.
var notificationCount = 1;
for (var i = 0; i < notifications.length; i++) {
var existingNotification = notifications[i];
if (existingNotification.data && existingNotification.data.notificationCount) {
notificationCount += existingNotification.data.notificationCount;
} else {
notificationCount++;
}
existingNotification.close();
}
نکته ظریفی که باید برجسته شود این است که برای اطمینان از حذف اعلان از لیست اعلان، باید close()
کنید. این یک اشکال در کروم است زیرا هر اعلان با اعلان بعدی جایگزین می شود زیرا از همان برچسب استفاده می شود. در حال حاضر این جایگزینی در آرایه برگشتی از getNotifications()
منعکس نمی شود.
این تنها یک نمونه از getNotifications() است و همانطور که می توانید تصور کنید، این API طیف وسیعی از موارد استفاده دیگر را باز می کند.
NotificationOptions.vibrate
از Chrome 45 میتوانید هنگام ایجاد اعلان، یک الگوی لرزش مشخص کنید. در دستگاههایی که از Vibration API پشتیبانی میکنند - در حال حاضر فقط Chrome برای Android - این به شما امکان میدهد الگوی لرزشی را که هنگام نمایش اعلان استفاده میشود، سفارشی کنید.
یک الگوی ارتعاشی می تواند آرایه ای از اعداد یا یک عدد واحد باشد که به عنوان آرایه ای از یک عدد در نظر گرفته می شود. مقادیر موجود در آرایه زمانها را بر حسب میلیثانیه نشان میدهند، با شاخصهای زوج (0، 2، 4، ...) مدت زمان ارتعاش، و شاخصهای فرد مدت زمان توقف قبل از ارتعاش بعدی است.
self.registration.showNotification('Buzz!', {
body: 'Bzzz bzzzz',
vibrate: [300, 100, 400] // Vibrate 300ms, pause 100ms, then vibrate 400ms
});
درخواستهای ویژگی مشترک باقی مانده
یکی از درخواستهای مشترک باقیمانده از سوی توسعهدهندگان، امکان بستن یک اعلان پس از یک دوره زمانی خاص یا امکان ارسال یک اعلان فشاری با هدف بستن یک اعلان در صورت مشاهده است.
در حال حاضر راهی وجود ندارد که بتوانید این کار را انجام دهید و هیچ چیزی در مشخصات وجود ندارد که به آن اجازه دهد :( اما تیم مهندسی کروم از این مورد استفاده آگاه است.
اعلان های اندروید
در دسکتاپ می توانید یک اعلان با کد زیر ایجاد کنید:
new Notification('Hello', {body: 'Yay!'});
به دلیل محدودیتهای پلتفرم، این هرگز در Android پشتیبانی نمیشود: به طور خاص، Chrome نمیتواند از تماسهای برگشتی در شی Notification، مانند onclick، پشتیبانی کند. اما در دسکتاپ برای نمایش اعلانهای برنامههای وب که ممکن است در حال حاضر باز کرده باشید، استفاده میشود.
تنها دلیلی که به آن اشاره می کنم این است که در اصل، یک تشخیص ویژگی ساده مانند مورد زیر به شما کمک می کند از دسکتاپ پشتیبانی کنید و هیچ خطایی در اندروید ایجاد نکنید:
if (!'Notification' in window) {
// Notifications aren't supported
return;
}
با این حال، با پشتیبانی از اعلانهای فشاری اکنون در Chrome for Android، اعلانها را میتوان از یک ServiceWorker ایجاد کرد، اما نه از یک صفحه وب، به این معنی که تشخیص این ویژگی دیگر مناسب نیست. اگر سعی کنید یک اعلان در Chrome for Android ایجاد کنید، این پیام خطا را دریافت خواهید کرد:
_Uncaught TypeError: Failed to construct 'Notification': Illegal constructor.
Use ServiceWorkerRegistration.showNotification() instead_
بهترین راه برای تشخیص ویژگی برای اندروید و دسکتاپ در حال حاضر انجام موارد زیر است:
function isNewNotificationSupported() {
if (!window.Notification || !Notification.requestPermission)
return false;
if (Notification.permission == 'granted')
throw new Error('You must only call this \*before\* calling
Notification.requestPermission(), otherwise this feature detect would bug the
user with an actual notification!');
try {
new Notification('');
} catch (e) {
if (e.name == 'TypeError')
return false;
}
return true;
}
این را می توان به این صورت استفاده کرد:
if (window.Notification && Notification.permission == 'granted') {
// We would only have prompted the user for permission if new
// Notification was supported (see below), so assume it is supported.
doStuffThatUsesNewNotification();
} else if (isNewNotificationSupported()) {
// new Notification is supported, so prompt the user for permission.
showOptInUIForNotifications();
}