服务工作者onClick事件 - 如何在带有sw范围的窗口中打开URL?

时间:2017-10-03 14:27:42

标签: javascript web-applications service-worker

我有服务工作者处理推送通知点击事件:

self.addEventListener('notificationclick', function (e) {
    e.notification.close();

     e.waitUntil(
        clients.openWindow(e.notification.data.url)
      );

});

当收到通知时,它会从数据中获取网址并在新窗口中显示。

代码有效,但是,我想要不同的行为。当用户单击链接时,它应检查服务工作者范围内是否有任何打开的窗口。如果是,那么它应该关注窗口并导航到给定的URL。

我已经检查了这个answer,但这并不是我想要的。

知道如何做到这一点吗?

P.S。我写了这段代码,但它仍然无效。但是,前两条消息显示在日志中。

self.addEventListener('notificationclick', function (e) {
    e.notification.close();
    var redirectUrl = e.notification.data.redirect_url.toString();
    var scopeUrl = e.notification.data.scope_url.toString();
    console.log(redirectUrl);
    console.log(scopeUrl);

    e.waitUntil(
        clients.matchAll({type: 'window'}).then(function(clients) {
            for (i = 0; i < clients.length; i++) {
                  console.log(clients[i].url);
                  if (clients[i].url.toString().indexOf(scopeUrl) !== -1) {
                        // Scope url is the part of main url
                        clients[i].navigate(givenUrl);
                        clients[i].focus();
                        break;
                  }
            }
        })
    );

});

2 个答案:

答案 0 :(得分:1)

如果我理解正确,您链接的大部分代码都可以在此处使用。

  • 首先检索所有客户
  • 如果有多个,请选择其中一个
    • 将其导航到某处并集中注意力
  • 否则打开一个新窗口

右?

event.waitUntil(
  clients.matchAll({type: 'window'})
    .then(clients => {
      // clients is an array with all the clients
      if (clients.length > 0) {
        // if you have multiple clients, decide
        // choose one of the clients here
        const someClient = clients[..someindex..]
        return someClient.navigate(navigationUrl)
          .then(client => client.focus());
      } else {
        // if you don't have any clients
        return clients.openWindow(navigationUrl);
      }
    })
);

答案 1 :(得分:0)

好的,这是一段按预期工作的代码。请注意,我将scope_url与redirect_url一起传递到Web通知中。之后,我正在检查scope_url是否是sw位置的一部分。只有在那之后我才导航到redirect_url。

self.addEventListener('notificationclick', function (e) {
    e.notification.close();
    var redirectUrl = e.notification.data.redirect_url;
    var scopeUrl = e.notification.data.scope_url;

    e.waitUntil(
        clients.matchAll({includeUncontrolled: true, type: 'window'}).then(function(clients) {
            for (i = 0; i < clients.length; i++) {
                  if (clients[i].url.indexOf(scopeUrl) !== -1) {
                        // Scope url is the part of main url
                        clients[i].navigate(redirectUrl);
                        clients[i].focus();
                        break;
                  }
            }
        })
    );

});