几秒钟后,阻止chrome.notifications API隐藏我的通知

 书友73277355 发布于 2023-02-13 14:15

我每天要做1-2次通知,重要的是用户不要错过它.有没有办法删除自动关闭,只允许用户手动关闭通知?

我在通知选项中看不到任何选项:

http://developer.chrome.com/extensions/notifications.html#type-NotificationOptions

2 个回答
  • 更新(2016-05-24):

    Xan评论说:

    有趣的事实:不再需要所有这些神秘的黑客行为; 看到新的requireInteraction旗帜

    它可用于Chrome 50. 更多信息.


    感谢root的评论,修改了这个答案,以解释onClosed在几秒钟后通知消失(进入notigications区域)时事件未被触发的事实.这仍然是一种hacky解决方案.


    背景

    您可以利用通知的生命周期以下列事件之一结束的事实:

    onClosed:当用户点击右上角的小'x'时.

    onClicked:当用户点击邮件正文时(不是'x',而不是某些按钮).

    onButtonClicked:当用户单击其中一个按钮(如果有)时.

    解决方案

    建议的解决方案包括以下步骤:

      注册上述所有事件的监听器.

      在几秒钟(例如30)之后注册超时 - 在隐藏通知之后 - 将删除并重新创建通知(因此它有效地保持在屏幕上可见.

      如果在步骤1中设置的任何侦听器触发,则表示用户与通知相互作用,因此取消超时(您不需要重新创建通知).

    写它很简单,编码需要更多的努力:)这是我用来实现上述内容的示例代码:

    manifest.json中:

    {
        "manifest_version": 2,
        "name":    "Test Extension",
        "version": "0.0",
    
        "background": {
            // We need this for the `Timeout` - see notes below
            "persistent": true,
            "scripts": ["background.js"]
        },
    
        "browser_action": {
            "default_title": "Test Extension"
            "default_icon": {
                "19": "img/icon19.png",
                "38": "img/icon38.png"
            },
        },
    
        "permissions": ["notifications"]
    }
    

    background.js中:

    var pendingNotifications = {};
    
    /* For demonstration purposes, the notification creation
     * is attached to the browser-action's `onClicked` event.
     * Change according to your needs. */
    chrome.browserAction.onClicked.addListener(function() {
        var dateStr = new Date().toUTCString();
        var details = {
            type:    "basic",
            iconUrl: "/img/notifIcon.png",
            title:   "REMINDER",
            message: dateStr + "\n\n"
                     + "There is one very important matter to attend to !\n"
                     + "Deal with it now ?",
            contextMessage: "Very important stuff...",
            buttons: [
                { title: "Yes" }, 
                { title: "No"  }
            ]
        };
        var listeners = {
            onButtonClicked: function(btnIdx) {
                if (btnIdx === 0) {
                    console.log(dateStr + ' - Clicked: "yes"');
                } else if (btnIdx === 1) {
                    console.log(dateStr + ' - Clicked: "no"');
                }
            },
            onClicked: function() {
                console.log(dateStr + ' - Clicked: "message-body"');
            },
            onClosed: function(byUser) {
                console.log(dateStr + ' - Closed: '
                            + (byUser ? 'by user' : 'automagically (!?)'));
            }
        };
    
        /* Create the notification */
        createNotification(details, listeners);
    });
    
    /* Create a notification and store references
     * of its "re-spawn" timer and event-listeners */
    function createNotification(details, listeners, notifId) {
        (notifId !== undefined) || (notifId = "");
        chrome.notifications.create(notifId, details, function(id) {
            console.log('Created notification "' + id + '" !');
            if (pendingNotifications[id] !== undefined) {
                clearTimeout(pendingNotifications[id].timer);
            }
    
            pendingNotifications[id] = {
                listeners: listeners,
                timer: setTimeout(function() {
                    console.log('Re-spawning notification "' + id + '"...');
                    destroyNotification(id, function(wasCleared) {
                        if (wasCleared) {
                            createNotification(details, listeners, id);
                        }
                    });
                }, 10000)
            };
        });
    }
    
    /* Completely remove a notification, cancelling its "re-spawn" timer (if any)
     * Optionally, supply it with a callback to execute upon successful removal */
    function destroyNotification(notifId, callback) {
    
        /* Cancel the "re-spawn" timer (if any) */
        if (pendingNotifications[notifId] !== undefined) {
            clearTimeout(pendingNotifications[notifId].timer);
            delete(pendingNotifications[notifId]);
        }
    
        /* Remove the notification itself */
        chrome.notifications.clear(notifId, function(wasCleared) {
            console.log('Destroyed notification "' + notifId + '" !');
    
            /* Execute the callback (if any) */
            callback && callback(wasCleared);
        });
    }
    
    /* Respond to the user's clicking one of the buttons */
    chrome.notifications.onButtonClicked.addListener(function(notifId, btnIdx) {
        if (pendingNotifications[notifId] !== undefined) {
            var handler = pendingNotifications[notifId].listeners.onButtonClicked;
            destroyNotification(notifId, handler(btnIdx));
        }
    });
    
    /* Respond to the user's clicking on the notification message-body */
    chrome.notifications.onClicked.addListener(function(notifId) {
        if (pendingNotifications[notifId] !== undefined) {
            var handler = pendingNotifications[notifId].listeners.onClicked;
            destroyNotification(notifId, handler());
        }
    });
    
    /* Respond to the user's clicking on the small 'x' in the top right corner */
    chrome.notifications.onClosed.addListener(function(notifId, byUser) {
        if (pendingNotifications[notifId] !== undefined) {
            var handler = pendingNotifications[notifId].listeners.onClosed;
            destroyNotification(notifId, handler(byUser));
        }
    });
    

    最后的说明:

    如果您的通知非常重要,您应该实施"恢复"机制,例如浏览器操作系统崩溃或突然终止.例如依靠更持久存储(localStorage,chrome.storageAPI等),上延伸部恢复待处理通知/浏览器的启动等.

    出于"用户友好性"的原因,对待处理通知的总数进行限制可能是个好主意.如果您的待处理通知在任何给定时刻超过,例如3,您可以将其替换为通知有待处理通知的通知,并将用户定向到您列出所有通知的页面.(代码会相当复杂,但对于用户来说嘿嘿,对吧?;)

    在用户决定处理它们之前,不要试图保持通知在屏幕上可见,最好使用徽章(可以有颜色和小文本 - 表示待处理通知的数量.

    我没有调查过,但是有可能(在这种情况下也是可行的)Timeoutchrome.alarmsAPI替换's 然后将后台页面转换为非持久性(也就是事件页面),这将是使它更加资源友好.

    2023-02-13 14:16 回答
  • 通知现在(自Chrome 50起)一个强制通知留在屏幕上的requireInteraction属性:

    var notification = new Notification("TITLE", {
              icon: 'assets/res/icon.png',
              body: "MESSAGE",
              requireInteraction: true     
    });
    

    onclick你必须关闭通知:

    notification.onclick = function()
    {
        this.close();
    }
    

    2023-02-13 14:16 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有