【问题标题】:Selecting <option> of a <select> from a Chrome extension content script从 Chrome 扩展内容脚本中选择 <select> 的 <option>
【发布时间】:2012-07-08 03:58:57
【问题描述】:

我绝望地试图从 Chrome 内容脚本中激活 change() 事件。 我浏览了网站和 Google 帖子,但仍然没有任何效果。

这是我想要达到的目标的描述;

考虑以下网页(如果有人愿意提供帮助,可以通过 http://www.gilzu.com/TFF/select.html 访问):

<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
    <title>Untitled Page</title>
    <script type="text/javascript" src="jquery.js"></script>
    <script type="text/javascript">
        $(document).ready(function () {
            $('#woot').die('change');
            $('#woot').live('change', function () {
                $('#description').text(jQuery('#woot').val());
                });
            console.log("window ready");       
        
            
            $("#meh").click(function() {
                $('#woot').val(15);
                $('#woot').change();
            });
            
            $('#woot').val(21);
            $('#woot').change();
        });
    </script>
</head>
<body>
    <p>
        <select id="woot">
            <option id="Option1" value="15">a</option>
            <option id="Option2" value="16">b</option>
            <option id="Option3" value="17">c</option>
            <option id="Option4" value="18">d</option>
            <option id="Option5" value="19">e</option>
            <option id="Option6" value="20">f</option>
            <option id="Option7" value="21">g</option>
        </select>
    </p>
    
    <p id="description"></p>
    <p><input type="button" id="meh" /></p>
</body>
</html>

做什么工作:

  1. 在启动时,change() 会启动并将选择框更新为 21,并在 div 上显示正确的值。
  2. 按下按钮#meh,将选择框更改为15,触发change()事件,在屏幕上显示正确的值。

到目前为止,没有任何意外。

所以我将通过以下方式访问内容脚本:

$(document).ready(function () {
                $('#woot').val(17);
                $('#woot').change();
                });

所以选择标签会更新,但change() 事件不会触发。

我已经阅读了有关 Chrome 扩展隔离世界的论坛,并对这个理论进行了测试:

$(document).ready( function() {
    $("#meh").click();
});

它实际上同时触发了点击事件和选择框的更改事件!

另外,为了反驳另一篇声称 js 代码注入有效的帖子:

$(document).ready( function() {
    var x = $("<script type='text/javascript' />");
    $(x).text("$('#woot').val(18); $('#woot').change();");
    $("head").append(x);        
});

问题相同的效果:选择框更新但更改事件不触发。

我还尝试了以下方法:

  1. 创建一个按钮,例如示例的#meh,并带有触发选择标签change() 的附加点击事件。只有选择更新,没有事件触发。
  2. 通过attr()prop()val() 更改选择框的值仅更新选择,不触发任何事件。
  3. 通过change()、trigger('change') 和selectedIndex 仅触发事件更新,不会触发事件。
  4. 通过js延迟命令
  5. 使用focus()另一个控件,这个控件甚至blur() 一些帖子建议的选择框。

您的帮助将不胜感激

【问题讨论】:

  • 注意:内容脚本确实在一个孤立的上下文中运行,它们只能访问页面的 DOM。该页面的window 对象不可直接访问,但document 可以。
  • 尝试将您的脚本注入页面...我posted an answer here 与 Greasemonkey 相关,但它也应该在这里工作。
  • @fudgey - 检查最后一个代码。正是你在 jQuery 中所说的。更新选择但不触发事件。

标签: jquery google-chrome google-chrome-extension jquery-events content-script


【解决方案1】:

您可以附加脚本。这将需要大量脚本附加,但您始终可以放置一个自定义通信事件,并且只注入一个好的脚本来监听该自定义事件并eval()ing 事件数据。如果没有 CSP,它将起作用。

var RunInThisContext = function(c){ try{
    var code = document.createTextNode(c);
    var script = document.createElement('script');
    script.type='text/javascript';
    script.language='javascript';
    script.appendChild(code);
    try{document.body.appendChild(script);}catch(e){document.head.appendChild(script);}

}catch(e){ console.error('ERROR: '+e); }}; 

这样使用:

RunInThisContext('('+(function(){ 
     $('select').change();
}).toString()+'()); '); 

但请记住,您是直接将其运行到页面中。如果页面没有 jQuery,则必须先包含它。

【讨论】:

  • 为什么这与问题中的最后一段代码不同?他将 JS 注入到页面的 head 元素中。
  • 编辑(5 分钟已到):嗯,你是对的,我刚刚测试过它可以工作。 +1
  • @Menahem jQuery 的 append()/appendTo() with script 标签控制该脚本的执行,这将导致 jQuery 在内容脚本的隔离上下文中执行该脚本。
  • 感谢您的回复。如果您能抽出时间来解释一下,您的处理方式与问题中最后一段代码的处理方式有何不同?
  • @Menahem Grosso-modo when you do $('&lt;script&gt;') jQuery 接受它,创建一个不可见的 div,将 html 代码附加到文档并尝试计算 dom 树、样式、宽度/高度值等. 不幸的是,这一步也解释了脚本。这就是区别。
【解决方案2】:

我真的不知道 JQuery,但这里是如何在没有 JQuery 并且不向页面中注入任何内容的情况下做到这一点......

var selections = document.querySelector('#woot');

selections.value = 17;

var evt = document.createEvent("HTMLEvents");
evt.initEvent("change", true, true);
selections.dispatchEvent(evt);

【讨论】:

  • 太棒了!它比注入代码更有效,更优雅:)
  • 魔术!这为我节省了一吨。谢谢你。 :-)
  • 谢谢!但是为什么 jquery 不能这样做呢?
  • @dev-siberia 我相信你可以,但我没有,所以我没有。
猜你喜欢
  • 1970-01-01
  • 2023-03-21
  • 1970-01-01
  • 2019-11-05
  • 2012-07-04
  • 2021-06-15
  • 1970-01-01
相关资源
最近更新 更多