4

I'm writing a bookmarklet using jQuery. It looks like javascript:document.write('<script src="path/to/loader.js"></script>'), and loader.js does the initializing stuffs:

check_the_environment();

document.head.innerHTML='<meta charset=utf-8>';
document.body.innerHTML='(the webpage)';

var jq=document.createElement('script');
jq.src='path/to/jquery.min.js';
document.head.appendChild(jq);

function load_core() {
    if(window.$)
        eval('(core js code)');
    else
      setTimeout(load_core,50);
}
load_core();

The loader loads the core javascript code after the jQuery is available.

But sometimes I get this error in my core code:

$(...).on is not a function

It seems that jQuery was still initializing itself although $ variable is setted.

So, I need to wait for jQuery to be completely initialized before the loader loads the core code. How can I do that?

The traditional way of using $(document).ready(...) is infeasible, as jQuery is being loaded after the webpage is ready.

Here is a minimal Python code to check whether the solution is working:

import cherrypy

mod='''
var htmlroot=document.getElementsByTagName('html')[0];

function load_core() {
  if(window.jQuery)
    jQuery(function(){
        alert($(document).on);
    });
  else
    setTimeout(load_core,10);
}

if(!document.head)
  htmlroot.appendChild(document.createElement('head'));

var jquery=document.createElement('script');
jquery.src='http://libs.useso.com/js/jquery/2.1.1/jquery.min.js';
document.head.appendChild(jquery);

load_core();
'''

class Website:
    @cherrypy.expose()
    def mod(self,_time):
        return mod

    @cherrypy.expose()
    def index(self):
        return '''<a href="javascript:document.write('<script src=/mod/'+(+new Date())+' ></script>')">Mod</a>'''

cherrypy.quickstart(Website(),'/');
xmcp
  • 3,347
  • 2
  • 23
  • 36

2 Answers2

2

The right and foolproof way would be:

jQuery(function(){
    // code
});

Since jQuery may be loaded in noConflict mode the $ var may not have been initialized.

For the sake of productivity the following can also be used to have access to $ var inside the jQuery scope.

jQuery(function($){
    // you can use $ without worrying about conflicts now
});
2hamed
  • 8,719
  • 13
  • 69
  • 112
  • 1
    `jQuery` will still be undefined as script is loaded asynchronously..Will have to play with `onload` event I suppose... – Rayon Dec 14 '15 at 10:27
  • that solution is not working as the code inside `jQuery(function($){})` is NEVER being executed. see my question for a small program to verify that. – xmcp Dec 14 '15 at 10:59
0

You can check type of $ as below

if(typeof $ == "function"){
    //Jquery loaded
}