12

您可以通过运行提示用户允许或拒绝来自浏览器的桌面通知:

Notification.requestPermission(callback);

但是是否可以通过代码删除该权限?我们希望我们的用户可以选择切换通知。这可以通过 JavaScript 实现,还是我们需要将该选项保存在其他地方?

4

2 回答 2

16

查看MDNWHATWG关于Notification的文档,似乎没有办法请求撤销许可。但是,您可以使用localStorage模拟您自己的权限版本,以支持缺少的功能。假设您有一个切换通知的复选框。

<input type="checkbox" onChange="toggleNotificationPermission(this);" />

您可以将记住的权限notification-permission存储在本地存储中的密钥下,并更新权限状态类似于:

function toggleNotificationPermission(input) {
    if (Notification.permission === 'granted') {
        localStorage.setItem('notification-permission', input.checked ? 'granted' : 'denied');
    } else if (Notification.permission === 'denied') {
        localStorage.setItem('notification-permission', 'denied');
        input.checked = false;
    } else if (Notification.permission === 'default') {
        Notification.requestPermission(function(choice) {
            if (choice === 'granted') {
                localStorage.setItem('notification-permission', input.checked ? 'granted' : 'denied');
            } else {
                localStorage.setItem('notification-permission', 'denied');
                input.checked = false;
            }
        });
    }
}

您可以检索权限为:

function getNotificationPermission() {
    if (Notification.permission === 'granted') {
        return localStorage.getItem('notification-permission');
    } else {
        return Notification.permission;
    }
}

当您要显示通知时,请检查您的权限:

if (getNotificationPermission() === 'granted') {
    new Notification(/*...*/);
}
于 2015-02-12T13:25:04.593 回答
9

不,您的脚本无法以编程方式放弃显示通知的权限。API规范除了requestPermission. (当然,浏览器可能有一个选项菜单允许用户撤销对域的权限,但这是浏览器级别的选项,而不是站点级别的选项。例如,在 Chrome 中,您可以通过以下方式查看此选项菜单单击地址栏左侧的图标。)

如果您不想显示通知,请不要调用new Notification.

您可以将所有调用包装到new Notification内部条件:

if(notifications_allowed) {
    new Notification(...);
}

或者,您可以重写Notification构造函数以包含条件语句并Notification酌情调用原始构造函数:

(function() {
    var oldNofitication = Notification;
    Notification = function() {
        if(notifications_allowed) {
            oldNotification.apply(this, arguments);
        }
    }
})();

如果您使用以供应商为前缀的构造函数或函数(例如,webkitNotifications.createNotification),那么您还需要重写其中的每一个,以便以您的 options 变量为条件。

于 2015-02-12T13:19:23.347 回答