首页 > 解决方案 > 等待 inject.js 完全执行,然后再继续 popup.js

问题描述

我的 chrome 扩展有问题,该扩展从页面中读取一个对象并在 popup.js 中显示其内容。

要读取对象,popup 会执行 injects.js,然后再注入 script.js。

所以发生的事情是,当 inject.js 完成执行时 popup.js 回调被调用并被renderData(mydata) 执行。在 script.js 完全执行之前,我不希望这种情况发生

Popup.js

chrome.tabs.executeScript(null, { file: "inject.js" }, function() {
  renderData(mydata);
});

注入.js

var s = document.createElement("script");
s.src = chrome.runtime.getURL("script.js");
(document.head || document.documentElement).appendChild(s);

脚本.js

 var data = {
    type: "FROM_PAGE",
    text: JSON.stringify(WIO.sessionInfo.context)
  };
  window.postMessage(data, "*");

标签: javascriptgoogle-chromegoogle-chrome-extension

解决方案


问题是 executeScript 返回最后一个同步计算的表达式作为回调的参数,但 a scriptwithsrc异步运行。顺便说一句,您忘记指定参数。

使用textContentwith literal code 同步运行脚本并发送 DOM 消息,这也是同步的,然后将结果留在最后一个表达式中:

popup.js

chrome.tabs.executeScript(null, { file: "inject.js" }, ([mydata]) => {
  renderData(mydata);
});

注入.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;

或者,您可以使用扩展消息将数据发送到弹出窗口(示例)。


推荐阅读