如何在Chrome扩展程序中将数据从popup.js发送到content.js

rjjhvcjd  于 2023-06-19  发布在  Go
关注(0)|答案(2)|浏览(265)

我正在做一个chrome扩展,它将自动填充页面上的输入(在本例中是outlook主题行),我需要以某种方式将我从popup.js(扩展)上的输入中获得的消息传递到content.js中,以便我可以更新该页面上的DOM。
popup.html

<!DOCTYPE html>
<html>

<head>
    <link rel="stylesheet" href="style.css">
</head>

<body>
    <div class="container">
        <input type="text" id="message" name="message" placeholder="Enter a message..." class="message-input">
        <input type="submit" value="Set new message" id="message-btn" class="message-btn">
    </div>
</body>
<script src="popup.js"></script>

</html>

popup.js

let messageInput = document.getElementsByClassName('message-input')[0];
let updateMessageBtn = document.getElementById('message-btn');

updateMessageBtn.addEventListener('click', async(messageInput) => {
        // Query tab
    let queryOptions = { active: true, currentWindow: true };
    let tabs = await chrome.tabs.query(queryOptions);

    // Open up connection
    const port = chrome.tabs.connect(tabs[0].id, {
        name: "uiOps",
    });

        port.postMessage({
            message: messageInput.value
        });

            port.onMessage.addListener(function(msg) {
        if (msg.exists) {
            alert('Exists');
        } else {
            alert("Doesn't exist");
        }
    })
});

content.js

chrome.runtime.onConnect.addListener(function (port) {
  port.onMessage.addListener(function (msg) {
    if (port.name === "uiOps") {
      const idToQuery = msg.message;
      if (idToQuery) {
        port.postMessage({
          exists: true,
        });
      } else {
        port.postMessage({
          exists: false,
        });
      }
    }
  });
});

manifest.json

{
    "name": "Email Autofiller",
    "description": "Automatically fill email subject lines!",
    "version": "1.0",
    "manifest_version": 3,
    "permissions": ["storage", "activeTab", "scripting"],
    "action": {
        "default_popup": "popup.html",
        "default_icon": {
        "16": "/images/get_started16.png",
      "32": "/images/get_started32.png",
      "48": "/images/get_started48.png",
      "128": "/images/get_started128.png"
    }
    },
      "icons": {
    "16": "/images/get_started16.png",
    "32": "/images/get_started32.png",
    "48": "/images/get_started48.png",
    "128": "/images/get_started128.png"
  }
}

我已经尝试了很多不同的方法,包括尝试使用localstorage,但都不起作用。我想我走在正确的道路上,但谷歌Chrome扩展文档有点让我困惑。任何帮助是赞赏-谢谢!

3lxsmp7m

3lxsmp7m1#

我将分享一个我刚刚测试过的工作示例。下面的代码允许popup.js向content.js发送消息,反之亦然。
popup.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>ImageOps</title>
    <link rel="stylesheet" href="pico.min.css">
    <style>
        body {
            width: 200px;
            height: 200px;
        }
    </style>
</head>
<body>
    <button id="btn">Test</button>
    <p id="p"></p>
    <script src="popup.js"></script>
</body>
</html>

popup.js

let btn = document.getElementById('btn');
let p = document.getElementById('p');

btn.addEventListener('click', () => {
    send({
        doSomething: true
    });
});

async function send(message) {
    const [tab] = await chrome.tabs.query({ active: true, lastFocusedWindow: true });
    const response = await chrome.tabs.sendMessage(tab.id, message);
    // Optional: do something with response
}

chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
    if (message.finishedDoingSomething) {
        p.textContent = "All done doing something.";
    }
    // Optional: sendResponse({message: "goodbye"});
});

/**************************************************************************
Functions to inject content.js script
***************************************************************************/
async function getCurrentTab() {
    let queryOptions = { active: true };
    let [tab] = await chrome.tabs.query(queryOptions);
    return tab;
};

function injectContentScript(tab) {
    const { id, url } = tab;
    chrome.scripting.executeScript(
        {
            target: { tabId: id, allFrames: true },
            files: ['content.js']
        }
    );
};

getCurrentTab().then((tab) => {
    injectContentScript(tab);
});

content.js

chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
    if (message.doSomething) {
        doSomething();
    }
    // Optional: sendResponse({message: "goodbye"});
});

function doSomething() {
    console.log("The doSomething() function is being called.");
    send({
        finishedDoingSomething: true
    });
}

async function send(message) {
    const response = await chrome.runtime.sendMessage(message);
    // Optional: do something with response
}

manifest.json

{
    "manifest_version": 3,
    "name": "ImageOps",
    "version": "0.0.1",
    "action": {
        "default_popup": "popup/popup.html",
        "default_title": "ImageOps"
    },
    "description": "Image scraper and modifier",
    "icons": {},
    "permissions": [
        "scripting",
        "activeTab"
    ]
}
iswrvxsc

iswrvxsc2#

我将试着给你们提供一个具体的例子。首先,您需要修改manifest.json以添加内容脚本
manifest.json

"content_scripts": [ // add this
      {
         "matches": [
            "<all_urls>"
         ],
         "js": ["content.js"]
      }
   ],

然后,在content.js文件中,您将编写一个消息侦听器。
content.js

chrome.runtime.onMessage.addListener( // this is the message listener
    function(request, sender, sendResponse) {
        if (request.message === "autoFill")
            autoFill(request.textToFill);
    }
);

async function autoFill(textToFill){ // here write your function...
    console.log(textToFill)
}

现在您将从popup.js发送消息。
popup.js

chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
    chrome.tabs.sendMessage(tabs[0].id, 
        {
            message: "autoFill",
            textToFill: "some text" 
        }, function(response) {})
})

就是这样!
如果您需要任何更多的帮助或澄清随时发表评论。祝你的项目好运!

相关问题