Django和jQuery的难题(为什么在管理应用中$未定义?)

14 投票
8 回答
20467 浏览
提问于 2025-04-16 10:05

我有一段时间没用jQuery了,我觉得我可能犯了个傻瓜式的错误。

这是一个Django的小部件:

class FooWidget(Widget):

    # ...

    class Media:
        js = ('js/foowidget.js',)

这是.js文件:

alert("bar");

$(document).ready(function() {
  alert("omfg");
  $('.foo-widget').click(function() {
    alert("hi");
    return false;
  });
});

alert("foo");

唯一能弹出的alert()是第一个。我是不是写错了什么语法,还是别的什么问题?

另外,如果页面上有其他的脚本重新定义了$(document).ready,我需要担心这个吗?我猜后面的定义会覆盖我的,所以后面的定义最好做成这样:

$(document).ready(function() {
    document.ready()
    // real stuff
});

foowidget.js加载之前,jQuery已经被包含在页面中了。

更新:根据@lazerscience的链接,我尝试了下面的代码,但结果还是和之前一样失败:

alert("bar");

$(function() {
  alert("omfg");
  $(".set-widget").click(function() {
    alert("hi");
    return false;
  });
});

alert("foo");

更新2:奇怪的是,当我这样做的时候:

alert($);

我得到了“未定义”。这说明jQuery实际上没有初始化。这让我很困惑,因为<head>里包含了:

<script type="text/javascript" src="/media/js/jquery.min.js"></script>
<script type="text/javascript" src="/media/js/jquery.init.js"></script>
<script type="text/javascript" src="/media/js/actions.min.js"></script>
<script type="text/javascript" src="/static/js/foowidget.js"></script>

难道把我的脚本放在jQuery脚本之后就能确保$会被定义吗?

更新3:来自jquery.min.js的内容:

/*!
 * jQuery JavaScript Library v1.4.2
 * http://jquery.com/
 *
 * Copyright 2010, John Resig
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * Includes Sizzle.js
 * http://sizzlejs.com/
 * Copyright 2010, The Dojo Foundation
 * Released under the MIT, BSD, and GPL Licenses.
 *
 * Date: Sat Feb 13 22:33:48 2010 -0500
 */
(function(A,w){function ma(){if(!c.isReady){try{s.documentElement.doScroll("left")}catch(a){setTimeout(ma,1);return}c.ready()}}function Qa(a,b){b.src?c.ajax({url:b.src,async:false,dataType:"script"}):c.globalEval(b.text||b.textContent||b.innerHTML||"");b.parentNode&&b.parentNode.removeChild(b)}function X(a,b,d,f,e,j){var i=a.length;if(typeof b==="object"){for(var o in b)X(a,o,b[o],f,e,d);return a}if(d!==w){f=!j&&f&&c.isFunction(d);for(o=0;o<i;o++)e(a[o],b,f?d.call(a[o],o,e(a[o],b)):d,j);return a}return i? /* ... */

看起来是对的。

这是来自Firebug控制台的内容:

Error: $ is not a function
[Break On This Error] $(function() {
foowidget.js (line 5)
>>> $
anonymous()
>>> jQuery
undefined
>>> $('a')
null
>>> $(document)
null

更新4:在我的Django网站的所有页面上$都被定义了,除了管理应用。真奇怪……

更新5:这很有趣。

jQuery.init.js

// Puts the included jQuery into our own namespace
var django = {
 "jQuery": jQuery.noConflict(true)
}; 

来自控制台的内容:

>>> $
anonymous()
>>> django
Object {}
>>> django.jQuery
function()
>>> django.jQuery('a')
[a /admin/p..._change/, a /admin/logout/, a ../../, a ../, a.addlink add/]

8 个回答

8

我用这种方式解决了这个问题,你需要在这个文件里包含 jquery.init.js(通常是来自管理员的那个 jquery.init.js),然后添加以下几行代码:

var django = {
    "jQuery": jQuery.noConflict(true)
};
var jQuery = django.jQuery;
var $=jQuery;

这样你在整个工作区就可以使用 jquery 和 $ 了。为了让代码看起来更整洁,我更喜欢在项目里创建自己的 jquery 初始化文件。

31

把这个加到我 .js 文件的顶部就解决了问题:

var $ = django.jQuery;

我不太确定怎么去掉 jquery.init.js 这个文件,因为我的项目里没有任何脚本使用 $ 来做其他事情,除了 jQuery。

1

你可以在一页上随便使用 $(document).ready() 这个东西,没问题。它并不会像你想的那样“重新定义”什么,而是当文档准备好后,调用 ready() 会添加一些函数,这些函数会在文档准备好时被执行。想要调试你的代码的话,可以使用 Firebug,这个工具会告诉你错误发生的具体位置,如果有错误的话!

撰写回答