如何根据数据呈现 chrome 扩展名 UI?

How to render chrome extension UI depending on data?

我正在创建我的第一个 chrome 扩展,我需要根据我手动预先创建的一些数据加载扩展 HTML 后呈现扩展,不从任何外部服务器获取,我已经创建了扩展的所有必要资产,现在我需要使用 popup.js 来创建扩展标记

popup.js

  const body = document.getElementById('body') // extenstion HTML body
  const bookList = document.getElementById('book-list')

  body.addEventListener('load', async () => {
     let [tab] = await chrome.tabs.query({ active:true,currentWindow:true})

     chrome.scripting.executeScript({
         target: { tabId: tab.id },
         function: renderExtension,
     });

  });

 function renderExtension() {
   chrome.storage.sync.get("books", ({ books}) => {
     books.forEach(book=> {
       bookList.innerHTML += `<input placeholder=${book.name}>`
     })
   })
 }

并在 background.js

let books = [
   //books objects
]

chrome.runtime.onInstalled.addListener(() => {
  chrome.storage.sync.set({ books});

});

不幸的是,这不起作用,我在扩展中没有得到任何渲染,这是我的第一个扩展,所以可能我遗漏了一些东西,我需要知道我在这里做错了什么?

chrome.scripting.executeScript 在选项卡的活动网页中运行脚本,但弹出窗口是一个单独的页面,其中 chrome-extension:// URL 显示在单独的 window,与网页完全无关。您在 popup.html 中加载的 popup.js 脚本在 window 中运行,因此您应该直接访问其 windowdocument 和 DOM。

同样不需要后台脚本和存储,直接把数据放在popup.js:

const books = [
  {name: 'foo'},
  {name: 'bar'},
];

document.getElementById('book-list').innerHTML =
  books.map(b => `<input placeholder=${b.name}>`).join('');

也无需等待 load,只需将您的脚本放在 popup.html:

正文的末尾
<body>
  <div id="book-list"></div>
  <script src=popup.js></script>
</body>