How to provide $ to third-party, external jQuery p

2020-05-24 05:13发布

I've included a couple of third-party jQuery plugins in my Django admin base template which assume "$" to be available.

For my own code, I've always been happy to just do

(function($) {
    my_code = 'here';
})(django.jQuery);

but how can I provide "$" to other people's code which sits in external files?

<script src="{{ STATIC_URL }}js/jquery.json-2.2.min.js" type="text/javascript"></script>

complains that "$" is undefined. I've tried to put

<script type="text/javascript">var $ = django.jQuery;</script>

before that external reference, but to no avail (btw, why is that? I understand loading happens concurrently, but execution? I can use that "$" immediately after defining it.).

I'm happy with the jQuery version that Django admin provides and really don't want to load another one. I also don't want to edit someone else's plugin so that it starts with the above "$" re-definition. EDIT: Neither do I want to wrap it like my own code, I just don't want to touch those files at all.

Do I really have to resort to putting $.getScript() - http://api.jquery.com/jQuery.getScript - into my anonymous function to load such files?

EDIT: After actually looking into that external file jquery.json-2.2.min.js, I saw it was already wrapped into a function that assumed "jQuery" to be available, rather than "$". After inserting

var jQuery = django.jQuery;

before the external reference, it worked fine. But is this really how this should be done?

3条回答
Lonely孤独者°
2楼-- · 2020-05-24 05:39

Override django's staticfile admin/js/jquery.init.js by creating a file with the same name and path in your app's staticfiles directory.

The original content is this

/* Puts the included jQuery into our own namespace using noConflict and passing
 * it 'true'. This ensures that the included jQuery doesn't pollute the global
 * namespace (i.e. this preserves pre-existing values for both window.$ and
 * window.jQuery).
 */
var django = {
    "jQuery": jQuery.noConflict(true)
};

Just remove the .noConflict(true).

查看更多
【Aperson】
3楼-- · 2020-05-24 05:44

For third party plugins, it's usually best to load your own copy of jQuery before including the other plugins. For Django 1.4+ this may look like so in your corresponding admin.py file:

class Media:
    js = (
        'http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js',
        '/static/js/third_party_plugin.js',
    )

If your plugins do not depend on a recent version of jQuery, you may also use Django's included version by defining $ and jQuery at the top of your plugin:

var jQuery = django.jQuery, $ = jQuery;

As of version 1.6, Django will ship with jQuery 1.9.1. Before that, jQuery 1.4 is used, which does not work for a lot of new/updated plugins.

查看更多
太酷不给撩
4楼-- · 2020-05-24 05:56

Yeah, I remember this problem. I feel your pain.

A great workaround is to restructure your js files in such a way that Django can read them as URLs. In your URLs file, add the pattern below:

urlpatterns = patterns((r"^js(?:/(?P<type>\w+))?", "app.views.render_js"))

Now, in your init.py, add the following code:

JS_FILES = {"name" : "name.js",
            "thing" : "thing.js"};

def render_main_js(req, type = None) :
    return render_to_response(JS_FILES.get(type, "main.js"), mimetype="text/javascript");

Once the code is in place and assuming you have your javascript files in /js/* you can include your javascript by using the code below:

<script type="text/javascript" src="/js/name"></script>
<script type="text/javascript" src="/js/thing"></script>
查看更多
登录 后发表回答