如何解决chrome.runtime.onMessage.addListener的异步特性在事件处理程序上使用变量时导致问题
我在扩展程序弹出窗口上有一个按钮,当用户单击它时,我必须使用LatestIncomingChatsNumber值来验证网站中的DOM容器是否有子级,但是当我尝试在chrome消息侦听器之外使用该变量时我得到一个“未定义”。我意识到问题是由于chrome.runtime.onMessage.addListener的异步特性,因此每次我尝试在另一个事件处理程序中使用变量时,都会得到未定义的信息。有没有办法使用消息传递操作中的变量来实现onclick函数之类的功能?
内容脚本:
let incomingChatsNumber = incomingChatsContainer.children().length;
chrome.runtime.sendMessage({ incomingChatsNumber: incomingChatsNumber });
背景JS:
chrome.runtime.onMessage.addListener(function (message) {
let incomingChatsNumber = message.incomingChatsNumber;
chrome.runtime.sendMessage({ incomingChatsNumber: incomingChatsNumber });
});
弹出式JS:
let latestIncomingChatsNumber;
chrome.runtime.onMessage.addListener((message) => {
let incomingChatsNumber = message.incomingChatsNumber;
latestIncomingChatsNumber = incomingChatsNumber;
return true;
});
//#js-toggleSorting is the id of the button inside the popup window
$("#js-toggleSorting").on("click",function () {
//This console.log will get an "undefined"
console.log(latestIncomingChatsNumber);
}
更新:
我已经更新了内容脚本以存储如下值:
let latestIncomingChatsNumber = incomingChatsContainer.children().length;
chrome.storage.local.set(
{ latestIncomingChatsNumber: latestIncomingChatsNumber },function () {
//This works fine
console.log(`Value is set to + ${latestIncomingChatsNumber}`);
}
);
这就是我试图从popup.js中获取值的方式,请注意“ frontEndDev.js”(或者我从弹出窗口本身注入的内容脚本...。 )
"use strict";
function save_button_state() {
var buttonStateText = $("#js-toggleSorting").html();
var buttonStateAttribute = $("#js-toggleSorting").attr("data-click-state");
var sortMessage = $(".message").html();
chrome.storage.local.set(
{
buttonStateText: buttonStateText,buttonStateAttribute: buttonStateAttribute,sortMessage: sortMessage,},function () {
// console.log(
// `Saved State is: ${buttonStateText} and Saved Attribute is: ${buttonStateAttribute} and Saved Message is: ${sortMessage}`
// );
}
);
}
function get_button_state() {
chrome.storage.local.get(
["buttonStateText","buttonStateAttribute","sortMessage"],function (data) {
$(".message").html(data.sortMessage);
$("#js-toggleSorting").html(data.buttonStateText);
$("#js-toggleSorting").attr(
"data-click-state",data.buttonStateAttribute
);
}
);
}
$(document).ready(() => {
get_button_state();
chrome.tabs.executeScript(null,{
file: "libraries/jquery-3.5.1.min.js",});
let sortFunction = function (goSortParam) {
if (goSortParam) {
chrome.tabs.executeScript(
null,{ code: "var goSortParam=true;" },function () {
chrome.tabs.executeScript(null,{ file: "scripts/frontEndDev.js" });
}
);
} else {
chrome.tabs.executeScript(
null,{ code: "var goSortParam=false;" },{ file: "scripts/frontEndDev.js" });
}
);
}
};
let latestIncomingChatsNumber;
chrome.storage.local.get(["latestIncomingChatsNumber"],function (result) {
console.log("Value currently is " + result.latestIncomingChatsNumber);
latestIncomingChatsNumber = result.latestIncomingChatsNumber;
});
$("#js-toggleSorting").on("click",function () {
$(".message").html("");
console.log(latestIncomingChatsNumber);
if (latestIncomingChatsNumber <= 0) {
$(".message").html("<p>No Chats To Sort Yet</p>");
} else {
$(".message").html("<p>Sorting Chats</p>");
if ($(this).attr("data-click-state") == 1) {
$(this).attr("data-click-state",0);
$(".message").html("");
$(this).html("SORT INCOMING CHATS");
sortFunction(false);
} else {
$(this).attr("data-click-state",1);
$(this).html("STOP SORTING INCOMING CHATS");
sortFunction(true);
}
save_button_state();
}
});
});
这是manifest.json:
{
"manifest_version": 2,"name": "Chrome Extension","version": "1.0.0","author": "Jorge Páez","description": "Test","short_name": "Extension Test","background": {
"scripts": ["libraries/jquery-3.5.1.min.js","scripts/background.js"],"persistent": false
},"content_scripts": [
{
"matches": ["https://someurl*"],"css": ["styles/custom.css"],"js": ["libraries/jquery-3.5.1.min.js","scripts/content.js"]
}
],"web_accessible_resources": ["images/*.*","scripts/*.*","libraries/*.*"],"icons": {
"16": "icons/icon16.png","32": "icons/icon32.png","48": "icons/icon48.png","128": "icons/icon128.png"
},"permissions": ["activeTab","declarativeContent","storage"],"page_action": {
"default_title": "Extension","default_popup": "popup.html"
},"update_url": "xyz"
}
但是那个console.log仍然会给我一个未定义的值。我还不能这么说,我是chrome扩展和stil的新手,它试图弄清特殊消息传递和本地存储的细微差别,因此感谢您的耐心等待。
解决方法
请记住@wOxxOm的所有好的建议:
- 这里的主要问题是我在popup.js中注入了所谓的“内容脚本”(frontEndDev.js),因此我确实在“ frontEndDev”运行之前打开了弹出窗口,因此在页面加载完成之前,因此,来自网站的变量处于不确定状态。长话短说,我试图在变量不存在之前对其进行评估。
因此,要解决该问题,我将将变量值保存到通过清单插入的适当内容脚本的部分移到了content.js中:
//Getting the children from the DOM container on the website:
let latestIncomingChatsNumber = incomingChatsContainer.children().length;
let hasIncomingChats;
//If children then "true" if no children then "false"
if (latestIncomingChatsNumber > 0) {
hasIncomingChats = true;
} else {
hasIncomingChats = false;
}
//Saving the value to the local storage
chrome.storage.local.set(
{ hasIncomingChats: hasIncomingChats },function () {
console.log(
`Sending state of incoming chats to Extension set to: ${hasIncomingChats}`
);
}
);
然后,为了从popup.js中访问“ hasIncomingChats”变量(也正如@wOxxOm的建议,谢谢!),我从本地存储中获取了该变量:
let hasIncomingChats;
chrome.storage.local.get(["hasIncomingChats"],function (result) {
console.log(
`Zendesk,do incoming chats exist? ${result.hasIncomingChats}`
);
hasIncomingChats = result.hasIncomingChats;
});
然后我可以在同一popup.js中使用变量,如下所示:
$("#js-toggleSorting").on("click",function () {
$(".message").html();
//Using the variable "hasIncomingChats" coming from the local storage
if (hasIncomingChats === false) {
//Do stuff
} else {
//Do other Stuff
}
});
});
现在(我知道这是另一个问题),这是一个警告。由于该网站容器是动态的(html节点一直在进出,所以该弹出窗口将永远不会动态获得子代数),因此它将在第一次加载页面时存储“ hasIncomingChats”的值,并保持相同的值,直到即使容器在某个时候没有子页面,页面也会重新加载。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。