在内容脚本中使用 jquery 的 Chrome 扩展解决了创建对话框窗口时的错误

问题描述 投票:0回答:2

我尝试在我的 Chrome 扩展中使用 jQuery 和 jQuery-UI。 每次创建新选项卡时,我都尝试在内容脚本对话框窗口中创建,但我不断收到:

Property '$' of object [object Window] is not a function 

我想我在加载脚本时做错了什么。这是我所拥有的:

{
"name":"Sample",
"description":"This is a sample",
"manifest_version":2,
"version":"2",
"background":{
    "scripts":["background.js"]
},
"content_scripts": [
    {
      "matches": ["<all_urls>"],
      "js": ["jquery-1.8.3.min.js","jquery-ui.js","client.js","myscript.js"]
      "run_at":"document_end",
      "all_frames": true
    }
  ],
"web_accessible_resources": [
    "client.js","jquery-1.8.3.min.js","jquery-ui.js"
  ],
"permissions": [ 
        "unlimitedStorage",
        "http://*/",
        "<all_urls>",
        "tabs"
   ]
}


myscript.js(内容脚本):

var ss = document.createElement('script');
ss.type = "text/javascript";
ss.src = chrome.extension.getURL('jquery-1.8.3.min.js');
ss.onload = function() {
    ss.parentNode.removeChild(ss);
     console.log("jquery-1.8.3.min.js loaded");

};

var ss_ui = document.createElement('script');
ss_ui.type = "text/javascript";
ss_ui.src = chrome.extension.getURL('jquery-ui.js');
ss_ui.onload = function() {
    ss_ui.parentNode.removeChild(ss_ui);
    console.log("jquery-ui.js loaded");
};


var s = document.createElement('script');
s.type = "text/javascript";
s.src = chrome.extension.getURL('client.js');
s.onload = function() {
    s.parentNode.removeChild(s);
    console.log("client.js loaded");
};

        try{

            (document.head||document.documentElement).appendChild(ss);
            (document.head||document.documentElement).appendChild(ss_ui);
            (document.head||document.documentElement).appendChild(s);

        }catch(e){
          console.log("exception in appendChild");
        }  



client.js(我创建对话框的地方)

       try{
        console.log("Starting to create tabel");

        var layerNode= document.createElement('div');
            layerNode.setAttribute('id','dialog');
            layerNode.setAttribute('title','Basic dialog');
        var pNode= document.createElement('p');
            pNode.innerHTML = "This is the default dialog which is useful for displaying information. The dialog window can be moved, resized and closed with the 'x' icon.";

        layerNode.appendChild(pNode);
        document.body.appendChild(layerNode);


        jq162 = jQuery.noConflict(true);
(function($){
    $(document).ready(function() {
       $("#dialog" ).dialog();
    });
})(jq162);

        }
        catch(e){
          console.log("script in page exception in appendChild"+e);
          //alert(e);
        }  

当我在控制台中看到我得到的打印顺序时:

Starting to create tabel client.js:2
script in page exception in appendChildTypeError: Cannot call method 'dialog' of null client.js:26
client.js loaded chrome-extension://mmoccjinakdjcmhjdjghhjnihbfkkgkp/myscript.js:24
jquery-1.8.3.min.js loaded chrome-extension://mmoccjinakdjcmhjdjghhjnihbfkkgkp/myscript.js:6
jquery-ui.js loaded   

我在这里做错了什么?

jquery jquery-ui google-chrome-extension
2个回答
5
投票

通常的免责声明,我不是真的做 jQuery ......但我看到你的代码有一个明显的问题,所以试了一下......

摆脱 client.js,在将它注入的文件添加到清单的内容脚本部分后不再需要它。将它们添加到清单后,Chrome 现在将为您注入它们。一旦你这样做,它就开始工作了一半。

之后我注意到对话框出现但没有图形/样式,因此您需要将 css 文件添加到清单的内容脚本部分才能注入。现在有一些样式,但控制台说它无法获取样式所需的图形文件。

我不确定从 css 文件引用扩展目录中包含的图形文件的最佳方法是什么,所以我只是将所有图形转换为 dataurl 并将它们放入 css 文件中。你可以使用像这样的工具......

http://dataurl.net/#dataurlmaker

...完成它。

现在我们有一个漂亮的对话框。

清单.json

{
"name":"JQuery UI Dialog",
"description":"https://stackoverflow.com/questions/13669762/chrome-extention-using-jquery-in-content-script-resolve-error-when-creating-dial",
"manifest_version":2,
"version":"2",
"content_scripts": [
    {
      "matches": ["<all_urls>"],
      "js": ["jquery-1.8.3.min.js","jquery-ui.js","client.js"],
      "run_at":"document_end",
      "all_frames": true,
      "css":["jquery-ui-base64.css"]
    }
  ],
"web_accessible_resources": [
    "client.js","jquery-1.8.3.min.js","jquery-ui.js"
  ],
"permissions": [ 
        "unlimitedStorage",
        "http://*/",
        "<all_urls>",
        "tabs"
   ]
}

jquery-ui-base64.css
https://gist.github.com/4193693
觉得放在这里可能有点大

client.js

try {
  console.log("Starting to create tabel");

  var layerNode = document.createElement('div');
  layerNode.setAttribute('id', 'dialog');
  layerNode.setAttribute('title', 'Basic dialog');
  var pNode = document.createElement('p');
  pNode.innerHTML = "This is the default dialog which is useful for displaying information. The dialog window can be moved, resized and closed with the 'x' icon.";

  layerNode.appendChild(pNode);
  document.body.appendChild(layerNode);


  jq162 = jQuery.noConflict(true);
  (function($) {
    $(document).ready(function() {
      $("#dialog").dialog();
    });
  })(jq162);



} catch(e) {
  console.log("script in page exception in appendChild" + e);
  //alert(e);
}

编辑
使用 chrome i18n 支持,我们可以更改 css 中图像的 url,以便它们指向我们扩展中的文件。
https://stackoverflow.com/a/8864212/189093
所以这个……

url(images/ui-bg_flat_0_aaaaaa_40x100.png)

...变成...
url(chrome-extension://__MSG_@@extension_id__/images/ui-bg_flat_0_aaaaaa_40x100.png)

并且路径不再是相对的并且
__MSG_@@extension_id__
被替换为您的扩展程序的ID。
此外,所有以这种方式使用的图像都需要在 mainfest 的
web_accessible_resources
部分中声明。
所以,你清单中的那部分最终看起来像这样(注意我取出了你在那里的三个,它们不再需要包含在扩展中,因为它们现在由扩展注入)...

"web_accessible_resources": [
    "images/ui-bg_flat_75_ffffff_40x100.png","images/ui-icons_222222_256x240.png","images/ui-bg_highlight-soft_75_cccccc_1x100.png"
  ]

..我只包含了让我的测试工作所需的文件,您可能需要添加更多。检查脚本正在运行的页面上的控制台,它会告诉您需要添加哪些文件。
这是我测试中使用的同一个 css 文件的链接,其 url 已更新为以这种方式工作...
https://gist.github.com/4195616


0
投票

当你调用

jQuery.noConflict
然后
$
变量将不会被定义。

但是在

script.js
中,您在
$(document)
之后立即调用
noConflict
。我想你在打电话
(function($
后忘记了一条线
noConflict
.

你必须把你的代码改成这样:

jq162 = jQuery.noConflict(true);
(function($){
    $(document).ready(function() {
       $("#dialog" ).dialog();
    });
})(jq162);
© www.soinside.com 2019 - 2024. All rights reserved.