英文:
Wait for inject.js to execute completely before continuing in popup.js
问题
以下是翻译好的内容:
我在我的Chrome扩展程序中遇到了问题,该扩展程序从页面中读取一个对象,并在popup.js中显示其内容。
为了读取该对象,popup.js执行inject.js,而inject.js则注入了script.js。
所发生的情况是,当inject.js执行完成时,将调用popup.js回调,并执行renderData(mydata)
。我不希望这种情况发生,直到script.js完全执行。
Popup.js
chrome.tabs.executeScript(null, { file: "inject.js" }, function() {
renderData(mydata);
});
inject.js
var s = document.createElement("script");
s.src = chrome.runtime.getURL("script.js");
(document.head || document.documentElement).appendChild(s);
script.js
var data = {
type: "FROM_PAGE",
text: JSON.stringify(WIO.sessionInfo.context)
};
window.postMessage(data, "*");
英文:
I have a problem with my chrome extension, the extension reads an object from the page and displays its contents in popup.js.
To read the object, popup executes injects.js which in turn injects script.js.
So what happens is, when inject.js completes execution the popup.js callback is called and renderData(mydata)
is executed. I don't want this to happen until script.js is executed completely
Popup.js
chrome.tabs.executeScript(null, { file: "inject.js" }, function() {
renderData(mydata);
});
inject.js
var s = document.createElement("script");
s.src = chrome.runtime.getURL("script.js");
(document.head || document.documentElement).appendChild(s);
script.js
var data = {
type: "FROM_PAGE",
text: JSON.stringify(WIO.sessionInfo.context)
};
window.postMessage(data, "*");
答案1
得分: 1
问题在于executeScript
返回最后同步评估的表达式作为回调的参数,但带有src
的script
是异步运行的。顺便说一下,你忘记指定参数了。
使用textContent
与文字代码一起运行脚本,以同步方式运行并发送DOM消息,然后将结果留在最后的表达式中:
popup.js
chrome.tabs.executeScript(null, { file: "inject.js" }, ([mydata]) => {
renderData(mydata);
});
inject.js
var data;
var eventId = 'event' + Math.random();
document.addEventListener(eventId, e => {
data = JSON.parse(e.detail);
}, {once: true});
var script = document.createElement('script');
script.textContent = `(${eventId => {
var data = JSON.stringify(WIO.sessionInfo.context);
document.dispatchEvent(new CustomEvent(eventId, {detail: data}));
}})('${eventId}')`;
document.documentElement.appendChild(script);
script.remove();
data;
英文:
The problem is that executeScript returns the last synchronously evaluated expression as the callback's parameter but a script
with src
runs asynchronously. BTW you forgot to specify the parameter.
Use textContent
with literal code to run the script synchronously and send a DOM message, which is also synchronous, then leave the result in the last expression:
popup.js
chrome.tabs.executeScript(null, { file: "inject.js" }, ([mydata]) => {
renderData(mydata);
});
inject.js
var data;
var eventId = 'event' + Math.random();
document.addEventListener(eventId, e => {
data = JSON.parse(e.detail);
}, {once: true});
var script = document.createElement('script');
script.textContent = `(${eventId => {
var data = JSON.stringify(WIO.sessionInfo.context);
document.dispatchEvent(new CustomEvent(eventId, {detail: data}));
}})('${eventId}')`;
document.documentElement.appendChild(script);
script.remove();
data;
Alternatively you can use extension messaging to send the data to the popup (example).
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论