在popup.js中,在继续之前等待inject.js完全执行。

huangapple go评论81阅读模式
英文:

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返回最后同步评估的表达式作为回调的参数,但带有srcscript是异步运行的。顺便说一下,你忘记指定参数了。

使用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).

huangapple
  • 本文由 发表于 2020年1月7日 00:23:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/59615547.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定