jquery Notification.requestPermission在Mac版本的Safari中引发错误

cyvaqqii  于 2023-10-17  发布在  jQuery
关注(0)|答案(5)|浏览(123)

我正在尝试在页面加载时使用jQuery本地显示通知。通知在Firefox、Firefox Developer和Chrome中正确显示。通知未显示在Safari中,尽管通知首选项设置允许。
类似的代码在MDN站点https://developer.mozilla.org/en/docs/Web/API/notification上运行。
鼻涕虫在下面。

  1. // Display a sample notification
  2. if (window.Notification) {
  3. return $(".au-notifications-page").show(function() {
  4. var notification;
  5. notification = new Notification(
  6. 'Success Text', {
  7. //tag: $("[name=tag]").val(),
  8. body: 'Success Message',
  9. iconUrl: 'img/avatar-male.png',
  10. icon: 'img/avatar-male.png'
  11. });
  12. return notification.onclick = function() {
  13. notification.close();
  14. window.open().close();
  15. return window.focus();
  16. };
  17. });
  18. };

完整代码在下面。

  1. $(document).ready(function () {
  2. // Request permission on site load
  3. Notification.requestPermission().then(function(result) {
  4. if (result === 'denied') {
  5. //alert('denied');
  6. $(".au-notif-disabled-header").removeClass('hide');
  7. $(".au-notif-disabled-header .btn").addClass('hide');
  8. return;
  9. }
  10. if (result === 'default') {
  11. //alert('ignored');
  12. $(".au-notif-disabled-header").removeClass('hide');
  13. return;
  14. }
  15. //alert('granted');
  16. $(".au-notif-disabled-header").addClass('hide');
  17. });
  18. // Request permission with button
  19. $('.au-notif-disabled-header .btn').click(function () {
  20. Notification.requestPermission().then(function(result) {
  21. if (result === 'denied') {
  22. $(".au-notif-disabled-header").removeClass('hide');
  23. $(".au-notif-disabled-header .btn").addClass('hide');
  24. return;
  25. }
  26. if (result === 'default') {
  27. $(".au-notif-disabled-header").removeClass('hide');
  28. return;
  29. }
  30. $(".au-notif-disabled-header").addClass('hide');
  31. });
  32. });
  33. $( ".au-notification-icon" ).hover(
  34. function() {
  35. $(".au-notifications-menu .au-notif-msg-realtime").slideDown();
  36. $('.au-notification-icon .badge').html("2");
  37. }, function() {
  38. $(".au-notifications-menu .au-notif-msg-realtime").slideUp();
  39. $('.au-notification-icon .badge').html("1");
  40. }
  41. );
  42. //To show notification received while on notifications page
  43. $(".au-notif-msg-realtime").hide();
  44. //$(".au-notifications-page .au-notif-msg-realtime").slideDown();
  45. $(".au-notifications-page .au-notif-msg-realtime").slideDown({
  46. complete: function(){
  47. $('.au-notification-icon .badge').html("2");
  48. $('head title').html("(2) Notifications");
  49. }
  50. });
  51. // Display a sample notification
  52. if (window.Notification) {
  53. return $(".au-notifications-page").show(function() {
  54. var notification;
  55. notification = new Notification(
  56. 'Success Heading', {
  57. body: 'Success Text',
  58. iconUrl: 'img/avatar-male.png',
  59. icon: 'img/avatar-male.png'
  60. });
  61. return notification.onclick = function() {
  62. notification.close();
  63. window.open().close();
  64. return window.focus();
  65. };
  66. });
  67. };
  68. });

编辑1:Safari抛出此异常
undefined不是一个对象(正在计算“Notification.requestPermission(). then”)

w8ntj3qf

w8ntj3qf1#

你必须使用Safari的回调函数,因为它不返回Promise。
根据MDN
这使用了promise-version的方法,就像最近的实现(例如Firefox 47)所支持的那样。如果你想支持旧版本,你可能必须使用旧的回调版本,它看起来像这样:
下面是他们给出的示例代码:

  1. Notification.requestPermission(function (permission) {
  2. // If the user accepts, let's create a notification
  3. if (permission === "granted") {
  4. var notification = new Notification("Hi there!");
  5. }
  6. });

为了支持Safari通知,这是我最终的结果:

  1. try {
  2. Notification.requestPermission()
  3. .then(() => doSomething())
  4. } catch (error) {
  5. // Safari doesn't return a promise for requestPermissions and it
  6. // throws a TypeError. It takes a callback as the first argument
  7. // instead.
  8. if (error instanceof TypeError) {
  9. Notification.requestPermission(() => {
  10. doSomething();
  11. });
  12. } else {
  13. throw error;
  14. }
  15. }
展开查看全部
iklwldmw

iklwldmw2#

更好的解决方案是将结果 Package 在Promise中,然后 then(没有双关语)运行代码。此代码适用于所有浏览器(包括Safari),并且没有复杂的if块(概念在this question中详细讨论)

  1. Promise.resolve(Notification.requestPermission()).then(function(permission) {
  2. // Do something
  3. });

这是因为Promise.resolvePromise没有任何作用,但会将Safari requestPermission()转换为Promise
请注意,iOS Safari仍然不支持通知API,因此您需要check if it is available first

m0rkklqb

m0rkklqb3#

要返回一个promise,该promise在用户赠款或拒绝显示通知的权限之前不会解析:

  1. if (!permissionPromise && Notification.permission === 'granted' ) {
  2. permissionPromise = Promise.resolve(Notification.permission);
  3. }
  4. if (!permissionPromise) {
  5. permissionPromise = new Promise(function (resolve, reject) {
  6. // Safari uses callback, everything else uses a promise
  7. var maybePromise = $window.Notification.requestPermission(resolve, reject);
  8. if (maybePromise && maybePromise.then) {
  9. resolve(maybePromise);
  10. }
  11. });
  12. }
  13. return permissionPromise;
wn9m85ua

wn9m85ua4#

过时问题的现代解决方案:

  1. new Promise((resolve) => {
  2. Notification.requestPermission(resolve)?.then(resolve);
  3. }).then(permission => console.log(permission))

Safari只接受第一个回调,忽略?.then(...)。Chrome和FF可能会两次解决promise,但这并不重要。
与大多数投票的答案不同,这个答案没有两次请求权限,这在我的Safari v13.1.2中打开了2个权限弹出窗口。

v1uwarro

v1uwarro5#

  1. async function requestPermission() {
  2. return new Promise((resolve) => {
  3. const timeoutId = setInterval(() => {
  4. if (Notification.permission === 'granted') {
  5. handleComplete(Notification.permission);
  6. }
  7. }, 3000);
  8. const handleComplete = (permission) => {
  9. clearInterval(timeoutId);
  10. resolve(permission);
  11. };
  12. Notification.requestPermission(handleComplete)?.then?.(handleComplete);
  13. });
  14. }

相关问题