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

问题描述 投票:4回答:3

我正在尝试在页面加载时使用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抛出此异常

未定义不是对象(评估'Notification.requestPermission()。then')]

javascript jquery html safari web-notifications
3个回答
8
投票

您必须对Safari使用回调函数,因为它不会返回Promise。

根据MDN

这使用了该方法的promise-version,如最近所支持实现(例如Firefox47。)如果要支持较旧的版本,您可能必须使用较旧的回调版本,看起来像这样:

这是他们提供的示例代码:

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;                                                                                                                                                                                       
        }                                                                                                                                                                                                      
    }      

0
投票

一个更好的解决方案是将结果包装在Promise中,然后then(无双关语)运行您的代码。此代码可在所有浏览器(包括Safari)上运行,并且没有复杂的if块(有关概念,请参见this question中的详细讨论)

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

这是有效的,因为Promise.resolvePromise无效,但是会将Safari requestPermission()转换为Promise

请注意,iOS Safari仍不支持Notification API,因此您需要check if it available


-1
投票

我使用此代码检查浏览器是否与通知兼容

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;});}
© www.soinside.com 2019 - 2024. All rights reserved.