message.js 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. /* 跨页面通信js */
  2. /**
  3. *
  4. * @param {*} pageName 页面名称
  5. */
  6. function applicationListener(curPageName) {
  7. var cache = {
  8. opens: [],
  9. };
  10. function getPageName(pageName, type) {
  11. return '[channel-message]' + pageName + ':' + (type || '');
  12. };
  13. function getPageRunningName(pageName) {
  14. return getPageName(pageName, 'running');
  15. }
  16. function getMessage(e) {
  17. if(cache[e.key]) {
  18. cache[e.key].forEach(handler => {
  19. handler(JSON.parse(e.newValue));
  20. });
  21. }
  22. }
  23. function removeHandler() {
  24. window.localStorage.removeItem(getPageRunningName(location.pathname));
  25. window.removeEventListener('storage', getMessage);
  26. cache.opens.forEach(tab => {
  27. tab.close();
  28. });
  29. }
  30. // 持续监听状态
  31. window.addEventListener('storage', getMessage);
  32. window.addEventListener('beforeunload', removeHandler);
  33. // 当前页
  34. window.localStorage.setItem(getPageRunningName(location.pathname), 'true');
  35. return {
  36. // 判断是否打开当前页
  37. isOpen(pageName) {
  38. return !!window.localStorage.getItem(getPageRunningName(pageName));
  39. },
  40. // 页面在线状态
  41. open(url) {
  42. if(/^[\\/]/.test(url)) {
  43. url = location.origin + url;
  44. }
  45. var url = new URL(url);
  46. if(this.isOpen(url.pathname)) return;
  47. cache.opens.push(window.open(url));
  48. },
  49. // 广播自身状态
  50. dispatch(payload) {
  51. window.localStorage.setItem(getPageName(curPageName), JSON.stringify(payload));
  52. },
  53. // 接收其他页面状态
  54. addEventListener(pageName, handler) {
  55. var type = getPageName(pageName);
  56. if(!cache[type]) {
  57. cache[type] = [];
  58. }
  59. cache[type].push(handler);
  60. // 历史消息需要推一次(避免open后没有数据)
  61. var payload = window.localStorage.getItem(getPageName(pageName));
  62. if(payload !== null) {
  63. handler(JSON.parse(payload));
  64. }
  65. },
  66. };
  67. }