Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Chrome extension "$ is not defined" error

I am getting an error "$ is not defined" when I am working on my chrome extension.

This is my manifest file:

   {
      "name": "X",
      "description": "Snip this page",
      "version": "2.0",
      "permissions": [
        "activeTab"
      ],
      "background": {
        "scripts": ["background.js"],
        "persistent": false
      },
      "content_scripts":[{
        "matches" : ["<all_urls>"],
        "js": ["jquery-2.0.2.js","jquery.Jcrop.js"],
        "css": ["jquery.Jcrop.min.css"]
      }],
      "browser_action": {
        "default_title": "Snip this page"
      },
      "manifest_version": 2
    }

This is my background.js file:

chrome.browserAction.onClicked.addListener(function(tab){
  // No tabs or host permissions needed!
  chrome.tabs.executeScript({
    file: 'content.js'
  });
});

Lastly, the file where the error is triggered: content.js

console.log('1');
var jcropapi, boundx, boundy;
$('body').attr('id', 'target');
$(document).ready(function(){
    $('target').Jcrop();
    console.log('4');
    document.onkeydown = function(){
        if(window.event.keyCode==13){
            console.log('enter');
        }
    };
});

From my understanding, this happends because JQuery does not get loaded. However, I am loading it properly in the manifest, and jquery.js is also the first file that gets called in the manifest content script. Please help me in debugging. Thank You!

like image 340
chaitanya.varanasi Avatar asked Oct 05 '13 16:10

chaitanya.varanasi


2 Answers

This happens when the script that calls for jQuery loads prior to jQuery.js loading. In the example given by the question submitter, the background loads prior to the content script, and the content script loads jQuery itself after the background script calls for jQuery. This example can be fixed by having the background script load jQuery itself, like so:

 "background": {
    "scripts": ["jquery-2.0.2.js", "jquery.Jcrop.js", "background.js"],
    "persistent": false
  },  

Keep in mind also that js files listed in the manifest are loaded in the order they appear. For example, let's say that you have a file, "script.js", that contains:

console.log($('#elementID'));

If you write your manifest like this (WRONG), you'll get the error "$ is not defined":

"content_scripts": [
    {
        "js": [ 
            "script.js",
            "jquery.js" ]
    } 
]

Changing the manifest to this (RIGHT) will fix the error:

"content_scripts": [
    {
        "js": [ 
            "jquery.js",
            "script.js" ]
    } 
]

Note that "jquery.js" now precedes "script.js" and is therefore loaded first.

The problem can be seem intermittent because both scripts are loaded almost at the same time. If you change the script so that the call to jQuery is below some other javascript commands, the time it takes for those other commands to execute may be just enough time for jQuery.js to finish loading. So for example, if you wrote the manifest the wrong way above, you could also technically fix the error by changing the script.js file like so:

var t = setTimeout(function(){
     console.log($('#elementID'));
}, 1000);

The 1 second delay gives jQuery.js enough time to load, however, this is obviously not the ideal solution!

like image 71
mattthew Avatar answered Oct 22 '22 06:10

mattthew


This is happening because you are calling your script before the jQuery file.
The right one is this:

{
  "name": "X",
  "description": "Snip this page",
  "version": "2.0",
  "permissions": [
    "activeTab"
  ],
  "background": {
    "scripts": ["background.js"],
    "persistent": false
  },
  "content_scripts":[{
    "matches" : ["<all_urls>"],
    "js": ["jquery-2.0.2.js","yourscript.js"],
    "css": ["jquery.Jcrop.min.css"]
  }],
  "browser_action": {
    "default_title": "Snip this page"
  },
  "manifest_version": 2
}
like image 34
Akap Worldwide Avatar answered Oct 22 '22 06:10

Akap Worldwide