javascript - Chrome 扩展:chrome.runtime.onMessage.addListener 中的代码永远不会被执行
问题描述
尝试使用 sendMessage 方法将变量从内容脚本传递到 popup.js 时遇到了很多麻烦。
这是我向后台脚本发送消息的内容脚本,其中包含 DOM 节点的子节点数量:
let incomingChatsNumber = incomingChatsContainer.children().length;
chrome.runtime.sendMessage({ incomingChatsNumber: incomingChatsNumber });
然后 background.js 监听消息并将带有相同变量的消息本身发送到 popup.js:
chrome.runtime.onMessage.addListener(function (message, sender, sendResponse) {
let incomingChatsNumber = message.incomingChatsNumber;
chrome.runtime.sendMessage({ incomingChatsNumber: incomingChatsNumber });
});
在 popup.js 中,我有一个按钮,如果“incomingChatsNumber”大于 0(dom 容器有孩子),它将触发一些代码:
$("#js-toggleSorting").on("click", function () {
chrome.runtime.onMessage.addListener(function (message) {
let incomingChatsNumber = message.incomingChatsNumber;
if (incomingChatsNumber <= 0) {
$(".message").html("<p>No Chats To Sort, You Joker</p>");
} else {
$(".message").html("<p>Sorting Chats</p>");
//This code never gets executed
if ($("#js-toggleSorting").attr("data-click-state") == 1) {
$("#js-toggleSorting").attr("data-click-state", 0);
$("#js-toggleSorting").html("SORT INCOMING CHATS");
sortFunction(false);
} else {
$("#js-toggleSorting").attr("data-click-state", 1);
$("#js-toggleSorting").html("STOP SORTING INCOMING CHATS");
sortFunction(true);
}
save_button_state();
}
});
});
对我来说奇怪的是,popup.js 获得了正确的值,我什至可以对其进行控制台记录,但是一旦我在上面添加更多代码,如果有条件,即使条件可以执行,代码也永远不会被执行。
更新:
在进行了 ehab 建议的修改后,我意识到由于 chrome.runtime.onMessage.addListener 的异步性质,该变量一直是“未定义的”:
内容脚本:
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 });
});
Popup.js(这是我需要使用incomingChatsNumber 变量值的地方):
let latestIncomingChatsNumber;
chrome.runtime.onMessage.addListener(function (message) {
let incomingChatsNumber = message.incomingChatsNumber;
latestIncomingChatsNumber = incomingChatsNumber;
//This Works
console.log(latestIncomingChatsNumber);
});
//This will give me an undefined value
console.log(latestIncomingChatsNumber);
我知道我的问题与 chrome.* API 是异步的这一事实有关,因此 chrome.runtime... 和 console.log(...) 将同时执行,因此出现错误。那么如何在点击事件中使用 latestIncomingChatsNumber 变量呢?我是否必须先将“latestIncomingChatsNumber”保存到 chrome.runtime.onMessage.addListener 内的本地存储中?
解决方案
您不应该将事件侦听器放在另一个事件处理程序中,即使它做了您认为应该做的事情,这也是一种非常糟糕的做法,这将导致您在路上发生内存泄漏,并使代码难以阅读和语义不正确。
似乎基于查看您的代码,问题在于消息的处理程序被多次调用,因为在单击事件中添加了先前的事件侦听器
let latestIncomingChatsNumber
chrome.runtime.onMessage.addListener(function (message) {
let incomingChatsNumber = message.incomingChatsNumber;
// save this into the application state, i will use a parent scope variable you could use something else
latestIncomingChatsNumber = incomingChatsNumber
});
$("#js-toggleSorting").on("click", function () {
if (latestIncomingChatsNumber <= 0) {
$(".message").html("<p>No Chats To Sort, You Joker</p>");
} else {
$(".message").html("<p>Sorting Chats</p>");
//This code never gets executed
if ($("#js-toggleSorting").attr("data-click-state") == 1) {
$("#js-toggleSorting").attr("data-click-state", 0);
$("#js-toggleSorting").html("SORT INCOMING CHATS");
sortFunction(false);
} else {
$("#js-toggleSorting").attr("data-click-state", 1);
$("#js-toggleSorting").html("STOP SORTING INCOMING CHATS");
sortFunction(true);
}
save_button_state(); // i believe this function saves the attributes to the dom elements
}
});
如果save_button_state
做得好我共享的代码应该可以工作
推荐阅读
- excel - 如何在 Excel VBA 中将字典设置为字典值?
- r - 如何使用ggplot通过第三个分组变量对散点图中的离散变量进行排序?
- excel - 如何使用python在excel中显示数据?
- noclassdeffounderror - FlyWay NoClassDefFoundError
- nuget - TeamCity 克隆的构建配置因 NuGet 错误而失败
- javascript - master-atul/react-native-exception-handler - 不捕获 node_modules 中的错误
- microsoft-graph-api - Microsoft Teams:使用 Graph API 跟踪/列出通话中的参与者
- javascript - ClickEvent(或查询选择器)无法正常工作
- reactjs - 如何使用graphQL父参数
- ios - iOS 谷歌分析日落