防止chrome.notifications API在几秒钟后隐藏我的通知 [英] Prevent chrome.notifications API from hiding my notification after a few seconds

查看:179
本文介绍了防止chrome.notifications API在几秒钟后隐藏我的通知的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



我没有看到通知选项中的任何选项:



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

解决方案

UPDATE(2016-05- 24):

Xan评论


有趣的事实:所有这些奥术黑客不再需要;查看新的 requireInteraction 标志


自Chrome 50开始可用。更多信息



< hr>

感谢root的评论,这个答案被修改以解释 onClosed 事件没有被触发的事实几秒钟后通知消失(进入通知区域)。这仍然是一种解决方案。 背景 >

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


  • onClosed :当用户点击右上角的小'x'时。 onClicked :When用户点击邮件正文(不是'x',而不是某个按钮)。

  • onButtonClicked :当用户点击其中一个按钮)。



解决方案n



建议的解决方案由以下步骤组成:


  1. 注册侦听器上面提到的所有事件。

  2. 几秒钟后注册超时(例如, 30) - 在通知被隐藏之后 - 这会 删除 并重新 创建 (b)如果在步骤1中设置的任何侦听器触发,则表示用户与通知进行了交互,所以取消超时(你不需要重新创建通知)。

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


$ b

manifest.json 中: >
$ b

  {
manifest_version:2,
name:Test Extension,
版本:0.0,

背景:{
//我们需要这个时间out - 请参阅下面的注释
persistent:true,
scripts:[background.js]
},

browser_action:{
default_title:Test Extension
default_icon:{
19:img / icon19.png,
38:img / icon38。 png

},

permissions:[notifications]
}
$ b

background.js 中:

  var pendingNotifications = {}; 

/ *出于演示目的,创建通知的
*附加到浏览器操作的onClicked事件。
*根据您的需求进行更改。 * /
chrome.browserAction.onClicked.addListener(function(){
var dateStr = new Date()。toUTCString();
var details = {
type:basic ,
iconUrl:/img/notifIcon.png,
title:REMINDER,
message:dateStr +\\\
\\\

+There
+现在处理它?,
contextMessage:非常重要的东西......,
按钮:[
{title:Yes},
{title:No}
]
};
var listeners = {
onButtonClicked:function(btnIdx) {
if(btnIdx === 0){
console.log(dateStr +' - Clicked:yes');
} else if(btnIdx === 1){
console.log(dateStr +' - 点击:no');
}
},
onClicked:function(){
console.log(dat eStr +' - 点击:message-body');
},
onClosed:function(byUser){
console.log(dateStr +' - Closed:'
+(byUser?'by user':'automagically(!? )'));
}
};

/ *创建通知* /
createNotification(details,listeners);
});
$ b $ *创建通知并存储其重新生成计时器和事件监听器的引用
* * /
函数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] = {
监听者:
timer:setTimeout(function(){
console.log('Re-spawning notification''+ id +'...');
destroyNotification(id,function(wasCleared){
if(wasCleared){
createNotification(details,listeners,id);
}
});
},10000)
};
});
}

* *完全删除通知,取消其重新生成计时器(如果有的话)
*可选地,提供回调以在成功移除后执行* /
函数destroyNotification(notifId,callback){

/ *取消重新生成计时器(如果有)* /
if(pendingNotifications [notifId]!== undefined){
clearTimeout(pendingNotifications [notifId] .timer);
delete(pendingNotifications [notifId]);

$ b $ *删除通知本身* /
chrome.notifications.clear(notifId,function(wasCleared){
console.log('Destroyed notification '+ notifId +'!');

/ *执行回调(如果有)* /
回调&& callback(wasCleared);
});

$ b $ * / *响应用户点击其中一个按钮* /
chrome.notifications.onButtonClicked.addListener(function(notifId,btnIdx){
if (pendingNotifications [notifId]!== undefined){
var handler = pendingNotifications [notifId] .listeners.onButtonClicked;
destroyNotification(notifId,handler(btnIdx));
}
});
$ b $ *响应用户点击通知消息body * /
chrome.notifications.onClicked.addListener(function(notifId){
if(pendingNotifications [notifId] !==未定义){
var handler = pendingNotifications [notifId] .listeners.onClicked;
destroyNotification(notifId,handler());
}
});
$ b $ * / *响应用户点击右上角的小'x'* /
chrome.notifications.onClosed.addListener(函数(notifId,byUser){
if(pendingNotifications [notifId]!== undefined){
var handler = pendingNotifications [notifId] .listeners.onClosed;
destroyNotification(notifId,handler(byUser));
}
});






最后说明:如果你的通知是非常重要的,你应该实现一个恢复机制,例如浏览器操作系统崩溃或者突然终止。例如。依赖更持久的存储( localStorage chrome.storage API 等),在扩展/浏览器启动等时恢复待处理通知。
< sub>

  • 对于用户友好原因,限制待处理通知的总数可能是个好主意。如果您的待处理通知在任何特定时刻超过了3(例如3),则可以将其替换为通知存在未决通知的通知,并将用户引导至列出所有通知的页面。 (代码会更复杂,但嘿用户的任何东西,对吧?)
  • 不是试图保持通知在屏幕上可见,直到用户决定处理它们,使用 徽章 (可以有一个颜色和一个小文本 - 表示待处理通知的数量。)

  • 我还没有看过它,但它可能(在这种情况下,它也是可取的),用 替换 Timeout .com / extensions / alarms.htmlrel =nofollow noreferrer> chrome.alarms API ,然后将背景页面转换为非-persistent(又名 活动页面 ),这将使它更加资源友好。


  • I'm doing around 1-2 notifications a day and it's important the user doesn't miss it. Is there a way of removing the auto close and only allowing the user to manually close the notification?

    I don's see any option for this in the Notification Options:

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

    解决方案

    UPDATE (2016-05-24):

    Xan commented:

    Fun fact: all this arcane hacking is no longer needed; see the new requireInteraction flag

    It is availalbe since Chrome 50. More info.


    Thanks to root's comment, this answer is revised to account for the fact that the onClosed event is not fired when the notification disappears (into the notigications area) after a few seconds. This is still kind of a hacky solution.


    Background

    You can take advantage of the fact that a notification's life-cycle ends with one of the following events:

    • onClosed: When the user clicks on the small 'x' in the top-right corner.
    • onClicked: When the user clicks on the message body (not the 'x', not some button).
    • onButtonClicked: When the user clicks on one of the buttons (if any).

    The solution

    The proposed solution consists of the following steps:

    1. Register listeners for all the events mentioned above.
    2. Register a timeout after a few seconds (e.g. 30) -after the notification is hidden- that will delete and re-create the notification (so it effectively stays visible on the screen.
    3. If any of the listeners set on step 1 fires, it means the user interracted with the notification, so cancel the timeout (you don't need to re-create the notification).

    Writing about it is simple, coding takes some more effort :) Here is the sample code I used to achieve what is described above:

    In 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"]
    }
    

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


    Final notes:

    • If your notifications are extremely important, you should implement a "recovery" mechanism, for case such as browser os OS crashes or abrupt termination. E.g. relying on a more persistent storage (localStorage, chrome.storage API etc), resuming pending notifications on extension/browser start-up etc.
    • It might be a good idea to put a limit on the total number of pending notifications, for "user-friendliness" reasons. If your pending notifications exceed, say, 3 at any given moment, you could replace them with one that informs there are pending notifications and direct the user to a page where you list all of them. (The code will be considerably more complex, but hey anything for the user, right ? ;)
    • Instead of trying to keep the notifications visible on screen until the user decides to deal with them, it could be better using a Badge (wich can have a color and a small text - indicating the number of pending notifications.
    • I haven't looked into it, but it might be possible (in which case it is advisable as well) to replace the Timeout's with the chrome.alarms API and then convert the background-page to non-persistent (a.k.a. event-page) which will make it more resource-friendly.

    这篇关于防止chrome.notifications API在几秒钟后隐藏我的通知的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆