我正在尝试在页面加载时在本地显示jQuery通知。该通知在Firefox,Firefox Developer和Chrome中正确显示。尽管在通知偏好设置中允许,但通知不会出现在Safari中。
类似的代码来自MDN网站https://developer.mozilla.org/en/docs/Web/API/notification。
小部件在下面。
// Display a sample notification
if (window.Notification) {
return $(".au-notifications-page").show(function() {
var notification;
notification = new Notification(
'Success Text', {
//tag: $("[name=tag]").val(),
body: 'Success Message',
iconUrl: 'img/avatar-male.png',
icon: 'img/avatar-male.png'
});
return notification.onclick = function() {
notification.close();
window.open().close();
return window.focus();
};
});
};
完整代码如下。
$(document).ready(function () {
// Request permission on site load
Notification.requestPermission().then(function(result) {
if (result === 'denied') {
//alert('denied');
$(".au-notif-disabled-header").removeClass('hide');
$(".au-notif-disabled-header .btn").addClass('hide');
return;
}
if (result === 'default') {
//alert('ignored');
$(".au-notif-disabled-header").removeClass('hide');
return;
}
//alert('granted');
$(".au-notif-disabled-header").addClass('hide');
});
// Request permission with button
$('.au-notif-disabled-header .btn').click(function () {
Notification.requestPermission().then(function(result) {
if (result === 'denied') {
$(".au-notif-disabled-header").removeClass('hide');
$(".au-notif-disabled-header .btn").addClass('hide');
return;
}
if (result === 'default') {
$(".au-notif-disabled-header").removeClass('hide');
return;
}
$(".au-notif-disabled-header").addClass('hide');
});
});
$( ".au-notification-icon" ).hover(
function() {
$(".au-notifications-menu .au-notif-msg-realtime").slideDown();
$('.au-notification-icon .badge').html("2");
}, function() {
$(".au-notifications-menu .au-notif-msg-realtime").slideUp();
$('.au-notification-icon .badge').html("1");
}
);
//To show notification received while on notifications page
$(".au-notif-msg-realtime").hide();
//$(".au-notifications-page .au-notif-msg-realtime").slideDown();
$(".au-notifications-page .au-notif-msg-realtime").slideDown({
complete: function(){
$('.au-notification-icon .badge').html("2");
$('head title').html("(2) Notifications");
}
});
// Display a sample notification
if (window.Notification) {
return $(".au-notifications-page").show(function() {
var notification;
notification = new Notification(
'Success Heading', {
body: 'Success Text',
iconUrl: 'img/avatar-male.png',
icon: 'img/avatar-male.png'
});
return notification.onclick = function() {
notification.close();
window.open().close();
return window.focus();
};
});
};
});
编辑1:Safari抛出此异常
undefined is not an object (evaluating 'Notification.requestPermission().then')
答案 0 :(得分:8)
您必须为Safari使用回调函数,因为它不会返回Promise。
根据MDN:
这使用了最近支持的方法的promise-version 实现(例如Firefox 47)。如果你想支持 旧版本,您可能必须使用较旧的回调版本, 看起来像这样:
以下是他们提供的示例代码:
Notification.requestPermission(function (permission) {
// If the user accepts, let's create a notification
if (permission === "granted") {
var notification = new Notification("Hi there!");
}
});
为了支持Safari通知,这就是我最终的结果:
try {
Notification.requestPermission()
.then(() => doSomething())
} catch (error) {
// Safari doesn't return a promise for requestPermissions and it
// throws a TypeError. It takes a callback as the first argument
// instead.
if (error instanceof TypeError) {
Notification.requestPermission(() => {
doSomething();
});
} else {
throw error;
}
}
答案 1 :(得分:2)
一个更好的解决方案是将结果包装在Promise
中,然后 then (无双关语)运行您的代码。这段代码可在所有浏览器(包括Safari)上运行,并且没有复杂的if
块(在this question中详细讨论了概念)
Promise.resolve(Notification.requestPermission()).then(function(permission) {
// Do something
});
之所以可行,是因为Promise.resolve
对Promise
无效,但是会将Safari requestPermission()
转换为Promise
。
请注意,iOS Safari仍不支持Notification API,因此您需要check if it is available first
答案 2 :(得分:0)
我使用此代码来检查浏览器与通知的兼容性
if (!window.Notification || !Notification.requestPermission){console.log('This browserdoes not support desktop notification');return;}else{window.Notification.requestPermission(function(p)console.log('browser notification status = '+p);return;});}
答案 3 :(得分:0)
返回一个在用户授予或拒绝显示通知权限之前不会解析的承诺:
if (!permissionPromise && Notification.permission === 'granted' ) {
permissionPromise = Promise.resolve(Notification.permission);
}
if (!permissionPromise) {
permissionPromise = new Promise(function (resolve, reject) {
// Safari uses callback, everything else uses a promise
var maybePromise = $window.Notification.requestPermission(resolve, reject);
if (maybePromise && maybePromise.then) {
resolve(maybePromise);
}
});
}
return permissionPromise;