2016-12-29 44 views
0

彈出窗口上有一個按鈕。點擊後,popup.js將向background.js發送消息。它幾乎在所有時間都運行良好。但經過很長時間沒有操作鉻,當我點擊按鈕,消息發送(警告(「開始發送消息」)執行),但不能被background.js接收(警報(「開始渲染」))執行)。當我再點擊一次時,它有時會起作用。如果它仍然不起作用,我會再次點擊,第三次有更多的機會成功。這很奇怪。Chrome擴展程序:背景js偶爾不能接收Popup js的消息

我在popup.html中使用jquery,但我不認爲這很重要。 JavaScript代碼popup.js

$('#create).html(chrome.i18n.getMessage('create')) 
.on('click', function(){ 
    _current = null; 
    chrome.runtime.sendMessage({ 
     cmd: 'SITEMAP_DEFINE' 
    }); 
    alert("Start to send message"); 
    window.close(); 

})

JavaScript代碼background.js在您的幫助

var curTabId; //current tab in which scraper is going to scraping 
var devtoolPort; 
var coord; 
var sitemap; 
var finish = false; 


function sendMessage(msg) { 
    chrome.tabs.query({active: true, currentWindow: true}, function(tabs) { 
    chrome.tabs.sendMessage(tabs[0].id, msg); 
    }); 
} 

//detective devtools 
chrome.runtime.onConnect.addListener(function (port) { 
    if (port.name == "devtools-papa") { 
     devtoolPort = port; 
    } 
}); 

//tab update 
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) { 
    if(finish === false && coord && changeInfo.status == 'loading'){ 
     coord.onUpdate(tab); 
    } 
}) 
chrome.tabs.onRemoved.addListener(function(tabId, removeInfo) { 
    if(finish === false && coord && removeInfo.isWindowClosing === false){ 
     coord.onRemove(tabId); 
    } 
}) 
chrome.runtime.onMessage.addListener(function(msg, sender, callback){ 
    var p = msg.params; 

    //scrape 
    if(msg.cmd == 'START_SCRAPE'){ 
     sitemap = p.sitemap; 
     if(sitemap){ 
      finish = false; 
      coord = new Coordinator(sitemap, 0); 
      var page = coord.sitemap.pages[0]; 
      coord.openTab(page.id, page.link); 
     } 
    } 
    else if(msg.cmd == 'TEST_SCRAPE'){ 
     sitemap = p.sitemap; 
     if(sitemap){ 
      chrome.tabs.query({active: true, currentWindow: true}, function(tabs) { 
       var tab = tabs[0]; 
       sitemap.pages[0].link = tab.url; 
       finish = false; 
       coord = new Coordinator(sitemap, 20); 
       var page = coord.sitemap.pages[0]; 
       coord.openTab(page.id, page.link); 
      }) 
     } 
    } 
    else if(msg.cmd == 'SCRAPE_READY'){ 
     print(sender); 
     coord.readyForScrape(sender.tab.id); 
    } 
    else if(msg.cmd == 'TAB_CLICK'){ 
     coord.currentPage = sitemap.getPage(p.page); 
    } 

    //define 
    else if(msg.cmd == 'START_SELECT'){ 
     if(msg.tabId){ 
      chrome.tabs.sendMessage(msg.tabId, msg); 
     }else{ 
      sendMessage(msg); 
     } 
    } 
    else if(msg.cmd == 'END_SELECT'){ 
     if(devtoolPort){ 
      devtoolPort.postMessage(msg); 
     } 
     sendMessage(msg); 
    } 
    else if(msg.cmd == 'SITEMAP_DEFINE'){ 
     alert("Start to render"); 
     var url = p && p.url; 
     sitemap = p && p.sitemap; 
     chrome.tabs.query({active: true, currentWindow: true}, function(tabs) { 
      var tab = tabs[0]; 
      if(url && url != tab.url){ 
       chrome.tabs.create({url: url}, function(newTab){ 
        doInjectScript(newTab.id); 
       }) 
      }else{ 
       injectScript(tab.id); 
      } 
     }); 
    } 
    else if(msg.cmd == 'SITEMAP_DEFINE_END'){ 
     var _sm = p.sitemap; 
     chrome.tabs.query({active: true, currentWindow: true}, function(tabs) { 
      var tab = tabs[0]; 
      _sm.pages[0].link = tab.url; 
      saveSitemap(_sm); 
     }) 
    } 
    else if(msg.cmd == 'SITEMAP_DELETE'){ 
     deleteSitemap(p.sitemap); 
    } 
    else if(msg.cmd == 'DEFINE_PAGE_LOADED'){ 
     callback(sitemap); 
    } 
    else{ 
     sendMessage(msg); 
    } 
}); 

var print = function(msg){ 
    if(curTabId){ 
     chrome.tabs.sendMessage(curTabId, { 
      cmd: 'LOG', 
      params: msg 
     }); 
    }else{ 
     sendMessage(msg) 
    } 
} 

function saveSitemap(_sm){ 
    var id = _sm.id; 
    chrome.storage.local.get("sitemaps", function(db){ 
     var _sitemaps = db["sitemaps"]; 
     if(!_sitemaps || !_sitemaps.length){ 
      _sitemaps = [_sm]; 
     }else{ 
      var _idx = _sitemaps.findIndex(function(s){return s.id == id}); 
      if(_idx == -1){ 
       _sitemaps.push(_sm); 
      }else{ 
       _sitemaps.splice(_idx, 1, _sm); 
      } 
     } 
     var _db = {'sitemaps':_sitemaps} 
     chrome.storage.local.set(_db, function(){ 
      alert(chrome.i18n.getMessage('saved')); 
     }); 
    }) 
} 

function deleteSitemap(id){ 
    chrome.storage.local.get("sitemaps", function(db){ 
     var _sitemaps = db["sitemaps"]; 
     var index = _sitemaps.findIndex(function(s){return s.id == id}) 
     _sitemaps.splice(index, 1); 
     var _db = {'sitemaps':_sitemaps} 
     chrome.storage.local.set(_db, function(){ 
      alert(chrome.i18n.getMessage('deleted')); 
     }); 
    }) 
} 

function injectScript(tabId){ 
    var flag; 
    chrome.tabs.sendMessage(tabId, { 
     cmd: 'SELF_CHECK' 
    }, function(r){ 
     flag = r; 
    }); 
    setTimeout(function(){ 
     if(flag){ 
      chrome.tabs.executeScript(tabId, {file: "injected/define/initUI.js"}, function() {}); 
     }else{ 
      doInjectScript(tabId); 
     } 
    }, 200) 
} 

//Injected scripts will be removed once the tab reload again. 
function doInjectScript(tabId){ 
    chrome.tabs.executeScript(tabId, {file: "injected/listener.js"}); 
    chrome.tabs.executeScript(tabId, {file: "lib/jquery/jquery-2.1.1.min.js"}, function() { 
     chrome.tabs.executeScript(tabId, {file: "lib/model.js"}); 
     chrome.tabs.executeScript(tabId, {file: "lib/css-selector-generator.js"}, function() {}); 
     chrome.tabs.executeScript(tabId, {file: "injected/SelectTool.js"}, function() {}); 
     chrome.tabs.executeScript(tabId, {file: "injected/define/initUI.js"}, function() {}); 
     chrome.tabs.insertCSS(tabId, {file: "injected/injected.css", runAt: "document_end"}); 
    }); 
} 


function createResultTab(title, fields, data){ 
    chrome.tabs.create({url: chrome.extension.getURL('result/table.html')}, function(newTab){ 
     var tabId = newTab.id; 
     setTimeout(function(){ 
      chrome.tabs.sendMessage(tabId, { 
       cmd: 'RESULT', 
       params:{ 
        data: data, 
        title: title, 
        fields: fields 
       } 
      }); 
     }, 200) 
    }) 
} 

感謝。

+0

沒有看到doInjectScript代碼,我的猜測是它沒有考慮到執行chrome.tabs.create回調但標籤還沒有開始加載URL的情況。 – wOxxOm

+1

請將[問題]置於主題上:包括**完整** [mcve],表示重複問題*。包括* manifest.json *,一些背景/內容/彈出腳本/ HTML。尋求調試幫助的問題(「**爲什麼不是這個代碼工作?」)必須包括:►期望的行爲,►特定問題或錯誤*和*►在問題中重現問題所需的最短代碼**本身**。沒有明確問題陳述的問題對其他讀者無益。請參閱:「**如何創建[mcve] **」,[我可以在此處詢問哪些主題?](http://stackoverflow.com/help/on-topic)和[問]。 – Makyen

+0

謝謝wOxxOm。我認爲你不應該關心doInjectScript代碼,因爲代碼'alert(「Start to render」);''只是在'alert(「開始發送消息」)後才執行;''被執行。 –

回答

0

我在official document找到答案。 如果我們設置持久 = false,後臺js將在閒置時卸載。

{ 
    "name": "My extension", 
    ... 
    "background": { 
    "scripts": ["eventPage.js"], 
    "persistent": false 
    }, 
    ... 
} 

該文件告訴從內容腳本發送消息會導致背景js重新加載。但我猜彈出腳本的消息有問題。

因此,要麼更改彈出持續真正chrome.runtime.getBackgroundPage造成背景JS重裝將解決這個問題。

相關問題