Come hai notato correttamente, non è possibile inviare i dati direttamente al popup quando è chiuso. Quindi, stai inviando dati alla pagina di sfondo.
Quindi, quando si apre il popup, si desidera che i dati lì. Quindi, quali sono le opzioni?
Nota: questa risposta darà prima un cattivo consiglio e quindi migliorerà. Dal momento che OP sta imparando, è importante mostrare il processo di pensiero e il roadbumps.
La prima soluzione che mi viene in mente è la seguente: richiedi la pagina di sfondo, utilizzando nuovamente Messaggi. Avviso precoce: questo non funzionerà o funzionerà male
Prima di tutto, stabilire che ci possono essere diversi tipi di messaggi. Modificare il vostro codice di messaggistica corrente:
// content.js
chrome.runtime.sendMessage({type: "setCount", count: count});
// background.js
chrome.runtime.onMessage.addListener(
function(message, sender, sendResponse) {
switch(message.type) {
case "setCount":
temp = message.count;
break;
default:
console.error("Unrecognised message: ", message);
}
}
);
E ora, si potrebbe in teoria chiedere che nel popup:
// popup.js
chrome.runtime.sendMessage({type: "getCount"}, function(count) {
if(typeof count == "undefined") {
// That's kind of bad
} else {
// Use count
}
});
// background.js
chrome.runtime.onMessage.addListener(
function(message, sender, sendResponse) {
switch(message.type) {
case "setCount":
temp = message.count;
break;
case "getCount":
sendResponse(temp);
break;
default:
console.error("Unrecognised message: ", message);
}
}
);
Ora, quali sono i problemi con questo?
Qual è la durata di temp
? Hai esplicitamente dichiarato "persistent": false
in your manifest. Di conseguenza, la pagina di sfondo può essere scaricata in qualsiasi momento, cancellando lo stato come temp
.
È possibile risolvere il problema con "persistent": true
, ma continua a leggere.
Quale conto di tabulazione ci si aspetta di vedere? temp
avrà gli ultimi dati scritti, che potrebbero non essere la scheda corrente.
È possibile risolvere il problema mantenendo le schede (vedere cosa ho fatto lì?) su quale scheda inviato i dati, ad es. utilizzando:
// background.js
/* ... */
case "setCount":
temp[sender.tab.id] = message.count;
break;
case "getCount":
sendResponse(temp[message.id]);
break;
// popup.js
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
// tabs is a single-element array after this filtering
chrome.runtime.sendMessage({type: "getCount", id: tabs[0].id}, function(count) {
/* ... */
});
});
Tuttavia, è un sacco di lavoro, non è vero? Questa soluzione funziona bene anche se per i dati specifici non-tab, dopo aver fissato 1.
miglioramento successivo di prendere in considerazione: abbiamo bisogno lo sfondo della pagina per memorizzare il risultato per noi? Dopo tutto, chrome.storage
is a thing; è una memoria persistente a cui possono accedere tutti gli script di estensione (inclusi gli script di contenuto).
Questo riduce lo sfondo (e Messaging) fuori dal quadro:
// content.js
chrome.storage.local.set({count: count});
// popup.js
chrome.storage.local.get("count", function(data) {
if(typeof data.count == "undefined") {
// That's kind of bad
} else {
// Use data.count
}
});
Questo sembra più pulito, e ignora completamente il problema 1 dall'alto, ma il problema 2 ottiene più complicato. You can't directly set/read qualcosa come count[id]
nello spazio di archiviazione, è necessario leggere count
, modificarlo e riscriverlo. Può diventare lento e disordinato.
Aggiungete a ciò che gli script di contenuto non sono realmente a conoscenza del loro ID di tabulazione; dovrai imparare lo sfondo del messaggio solo per impararlo. Ugh. Non carino. Ancora una volta, questa è un'ottima soluzione per dati non specifici della scheda.
Allora la prossima domanda da porsi: perché abbiamo bisogno anche di una posizione centrale per memorizzare il risultato (specifico per scheda)? La durata del copione del contenuto è la durata della pagina. Puoi chiedere lo script del contenuto direttamente in qualsiasi momento. Compreso dal popup.
Aspetta, aspetta, non hai detto in alto non è possibile inviare i dati al popup? Beh, sì, kinda: quando non sai se è lì ad ascoltare. Ma se il popup chiede, allora deve essere pronto per ottenere una risposta, no?
Quindi, invertiamo la logica dello script del contenuto. Invece di inviare immediatamente i dati, aspettare e ascoltare le richieste:
chrome.runtime.onMessage.addListener(
function(message, sender, sendResponse) {
switch(message.type) {
case "getCount":
sendResponse(count);
break;
default:
console.error("Unrecognised message: ", message);
}
}
);
Poi, nel popup, abbiamo bisogno di interrogare la schedache contiene lo script contenuti. È una funzione di messaggistica diversa e dobbiamo specificare l'ID della scheda.
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
chrome.tabs.sendMessage(tabs[0].id, {type: "getCount"}, function(count) {
/* ... */
});
});
Ora è molto più pulito. Il problema 2 è risolto: chiediamo la scheda da cui vogliamo ascoltare. Il problema 1 sembra essere risolto: purché uno script contenga ciò di cui abbiamo bisogno, può rispondere.
Si noti, come ultima complicazione, che gli script di contenuto non vengono sempre iniettati quando ci si aspetta che: inizino solo ad attivarsi nella navigazione dopo l' l'estensione è stata (ri) caricata. Ecco lo an answer che lo spiega dettagliatamente. Può essere aggirato se lo si desidera, ma per ora solo un percorso di codice per esso:
function(count) {
if(typeof count == "undefined") {
// That's kind of bad
if(chrome.runtime.lastError) {
// We couldn't talk to the content script, probably it's not there
}
} else {
// Use count
}
}
molto approfondita come al solito – Auspex
Grazie @Xan per la risposta dettagliata. Solo i problemi che non riesco a risolvere con l'approccio 3 è - se invio un messaggio basato su tab da popup.js e lascia che lo script di contenuto restituisca i dati, cosa succede se l'utente passa a una scheda diversa e la scheda di script del contenuto non è più il scheda attiva? Il mio pop-up non mostrerà mai risultati? –
Se l'utente si sposta in una scheda diversa, il popup viene chiuso nel processo e non c'è nessun listener in ogni caso. Questo metodo è per qualcosa a cui lo script di contenuto può rispondere immediatamente. Se pensi che il popup possa chiudersi nel mezzo, devi lasciare che la tua pagina di sfondo parli e poi il popup estrae i dati da esso. – Xan