我正在开发一个 Chrome 扩展程序,用于自动向网站填充信息。
但是,当我处理这个“flatpickr”元素时,我遇到了一些问题。我尝试使用“flatpickr”实例的“setDate”函数,但总是出现“TypeError:无法读取未定义的属性”。
我检查了DevTool,发现网站已经加载了一个flatpickr模块。我的代码正在 DevTool 控制台中运行。
总而言之,我是否可以使用网站加载的 flatpickr 模块?或者我需要在我的脚本中导入一个吗?
我还不熟悉java脚本和网站结构。请给我一些想法或帮助!
网站HTML
//...
<div>
<div class="form-group" data-triptype="oneway">
<span class="material-icons-outlined">today</span>
<label for="">Date</label>
<input date="2024/01/22" flimit="" isdpromotion="false" type="hidden" slimit="2024/02/19" isspromotion="false" plimit="2024/01/26" name="toTimeInputField" limit="2024/02/19" id="toTimeInputField" class="uk-input out-date flatpickr-input" value="2024/01/22" isfreeseat="false"><input class="uk-input" placeholder="" tabindex="0" type="text" readonly="readonly">
</div>
// ...
</div>
//...
manifest.json
{
"manifest_version": 3,
"name": "AutoFill",
"version": "1.0",
"description": "",
"content_scripts": [
{
"matches": ["https://*"],
"js": ["query_page_script.js"]
}
],
"permissions": [
"storage"
],
"action": {
"default_popup": "popup/index.html"
}
}
query_page_script.js
const columns_name = [
'toTimeInputField'
];
const data = {
toTimeInputField: ['date', '2024/02/08']
};
columns_name.forEach(e => {
const target = document.getElementsByName(e);
if (target && data[e]) {
if (data[e][0] === 'date') {
target[0]._flatpickr.setDate(data[e][1], true, 'Y/d/m');
} else {
target[0].value = data[e];
}
};
console.log("End.");
});
网站执行世界
对于 chrome 扩展来说,javascript 执行环境分为 两个世界 :
“ISOLATED”:指定隔离世界,这是该扩展特有的执行环境。
“MAIN”:指定 DOM 的主世界,它是与宿主页面的 JavaScript 共享的执行环境。
为什么扩展程序中的代码不起作用?
您的代码不起作用的原因是它被作为
content script
注入,没有 world
选项:
"content_scripts": [
{
"matches": ["https://*"],
"js": ["query_page_script.js"]
}],
这将使扩展程序将
ISOLATED
选项的 world
值作为默认值,因此,将您的代码注入到与主网页的 javascript 环境完全隔离的环境中,如记录的。
为什么控制台中的代码可以工作?
简单地说,因为控制台默认显示来自所有“世界”的控制台日志,但它接收的输入将被分类到
MAIN
世界 - 与网站相同的环境,因此将像该网站的javascript代码一样正常工作.
解决方案
我相信在清单文件中添加
world
选项可以解决此问题。
"content_scripts": [
{
"matches": ["https://*"],
"js": ["query_page_script.js"]
"world": "MAIN"
}],
希望这能有所帮助!