如何以编程方式选择一个选项从chrome扩展内容脚本的select2
How to programmatically select an option in select2 from chrome extension content script?
我在StackOverflow上尝试了所有的答案。但是,我似乎无法通过编程方式根据选项的值选择选项。
我这样做从一个内容脚本在Chrome扩展->不知道如果这改变了什么。
我的代码如下:
chrome.runtime.onMessage.addListener(
function(response, sender, sendResponse){
if (typeof response === 'string' || response instanceof String){
var dropdown = false;
if ((document.getElementById(response)).nodeName == 'SELECT'){
//console.log('im here');
dropdown = true;
var options = $('#' + response).find('option');
var random_num = ~~((Math.random() * (options.length - 1)) + 1 );
var radnom_option = options[random_num];
var value = radnom_option.value;
var slctr = ('#' + response);
/*
I thought that the next two lines would change the selected option.
*/
$(slctr).val(value);
$(slctr).trigger('change.select2');
console.log($(slctr));
console.log(options);
console.log(random_num);
console.log(radnom_option);
console.log(value);
console.log(slctr);
}
dropdown = true;
sendResponse(dropdown);
}
});
当它运行时,控制台显示:
[select#entity_email_1_createPersonEmailType.form-control.entity_email.select2.required, context: document, selector: "#entity_email_1_createPersonEmailType"]
[option, option#option_business, option#option_other, option#option_personal, option#option_school, prevObject: init[1], context: document, selector: "#entity_email_1_createPersonEmailType option"]
2
<option id="option_other" data-option-id="option_other" value="916">Other</option>
916
#entity_email_1_createPersonEmailType
我想修改的那部分HTMl是:
<div
class="col-md-12"
>
<div class="form-group formGroup">
<label
class="control-label"
for="entity_email[1][quickAddPersonEmailType]"
>Email Type* </label>
<select
placeholder=""
class="form-control entity_email select2 required "
name="entity_email[1][email_type]"
id="entity_email_1_quickAddPersonEmailType"
title="Email Type"
data-field-suffix=""
data-field-name="email_type"
data-init-callback=""
data-field-alias="Email Type"
tabindex=""
data-field-required="entity_email" >
<option data-option-id="option_empty" value="">Select</option>
<option
id="option_business"
data-option-id="option_business"
value="915"
>Business</option>
<option
id="option_other"
data-option-id="option_other"
value="916"
>Other</option>
<option
id="option_personal"
data-option-id="option_personal"
value="913"
>Personal</option>
<option
id="option_school"
data-option-id="option_school"
value="914"
>School</option>
这就是我对控制台的期望。但是,select元素仍然保留在第一个选项"select"。此外,当我尝试在StackOverflow上概述的方法,其中包括调用select2()函数时,有一个TypeError说明select2()函数没有定义。但是,如果HTML包含select2元素,怎么会出现这种情况呢?
我在这里做错了什么?是否存在其他方法能够实现能够选择特定选项的最终目标?例如,我是否可以删除所有选项,然后在更改默认值的同时再次添加它们?
任何帮助都将非常感激。提前感谢。
我知道这已经很长时间了,但我有同样的问题,并设法"解决"它,所以万一有人偶然发现这个…
为什么你突出显示的两行不改变选择值的原因,是因为Chrome扩展的内容脚本的沙箱性质。内容脚本不能访问页面作用域,因此它们根本不能访问其中定义的任何对象。这是谷歌出于安全考虑故意设计的行为,您可以在官方文档中阅读更多关于它的信息。
当您运行所包含的代码时,所触发的事件不会到达页面中声明的任何事件侦听器,因为jQuery和select2实例不一样,所以什么也没有发生,正如您注意到的那样。
如果您绝对需要,您可以通过创建一个<script>
标记来绕过这个障碍,该标记带有一个立即调用的函数表达式(IIFE),用于触发,并将其插入DOM中。
const code = () => $('selector').val('some value').trigger('change.select2');
const script = <script>({code})();</script>;
document.body.appendChild(script);
如果您没有可用的JSX,您总是可以使用旧的方式:
var code = () => $('selector').val('some value').trigger('change.select2');
var script = document.createElement('script');
script.appendChild(document.createTextNode('('+ code +')();'));
document.body.appendChild(script);
如果您走这条路,请记住,在您包含在<script>
标记中的函数内部,您不能访问来自内容脚本范围的变量,因为它将在页面范围内运行。由于这是您的用例,我可以看到两种方法来减轻这种情况,
- 将函数的所有代码放入字符串中,并传递该字符串字符串作为脚本的内容,如…
var code = `() => $('${slctr}').val(${value});.trigger('change.select2');`;
var script = document.createElement('script');
script.appendChild(document.createTextNode('('+ code +')();'));
document.body.appendChild(script);
- 包括你需要的数据作为
data-
属性在脚本中,然后在函数中使用类似的东西拉数据例如script.getAttribute('data-selector')
,其中script
将插入HTMLScriptElement
(您将需要一种方法来访问该节点)。
var code = () => {
var script = document.getElementById('my-script-id');
var selector = script.getAttribute('data-selector');
var value = script.getAttribute('data-value');
$(selector).val(value).trigger('change.select2');
};
var script = document.createElement('script');
script.id = 'my-script-id';
script.setAttribute('data-selector', selector);
script.setAttribute('data-value', value);
script.appendChild(document.createTextNode('('+ code +')();'));
document.body.appendChild(script);
这是非常丑陋和黑客,但真的没有其他办法。
我想这已经表达了我的意思。好运。
- chrome扩展中的navigator.geolocation.getCurrentPosition
- chrome扩展:尽管运行了at:documentidle,js脚本还是过早启动
- chrome扩展更改主机/域警告
- 如何在chrome扩展中重定向到html页面
- Chrome扩展没有't在重新加载之前考虑期权价值
- 如何通过自己获得Chrome扩展的用户反馈/错误报告
- 试图阻止Chrome通过扩展关闭
- 如何在chrome扩展中存储数据/结果,以及如何使用setTimeout使其只被调用一次
- 从选项页面更新chrome扩展清单权限
- 如何将chrome扩展功能移植到移动设备(特别是jquery和trello)
- Chrome扩展:遍历不同的页面并收集数据
- Chrome扩展 chrome.storage 如何同时进行大量获取和设置并避免竞争条件
- Chrome扩展:Chrome.tabs.executeScript不工作
- 中的访问扩展chrome://extensions页
- 如何在扩展Chrome DevTool时检索请求的启动器
- Chrome扩展-Chrome报警API为创建的每个新报警重新安排所有报警
- 是否有任何方法来扩展chrome's __commandLineAPI
- 谷歌Chrome扩展Chrome .tab . onupdate . addlistener
- 创建在页面上注入脚本的扩展chrome内容
- Chrome扩展:Chrome扩展中未定义的变量,即使它存在于控制台中