Сложность с Django и jQuery (почему $undefined в приложении администратора?)

Прошло некоторое время с тех пор, как я работал с 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(), который срабатывает, является первым. У меня есть глупая синтаксическая ошибка или что-то еще?

Кроме того, если какой-либо другой включенный script на странице redefines $(document).ready, мне нужно беспокоиться об этом? Я предполагаю, что последующие определения будут отменять мои, поэтому для последующих определений более безопасно сделать что-то вроде:

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

jQuery уже включен в страницу к моменту foowidget.js.

Обновление. На основе ссылки @lazerscience я попробовал следующее вместо этого, но он по-прежнему работает не так:

alert("bar");

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

alert("foo");

Обновление 2: Любопытно, когда я это сделаю:

alert($);

Я получаю "undefined". Это говорит о том, что 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>

Не помещает ли мой 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, кроме приложения admin. Странно...

Обновление 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/]

Ответ 1

Вы можете использовать $(document).ready() столько раз, сколько хотите на одной странице. Он не переопределяет ничего, как вы его называете, но вызов ready() добавляет функции, вызываемые, когда "документ готов". Например, для отладки кода. используйте Firebug, который покажет вам более подробную информацию о том, где происходит ошибка, если есть!

Ответ 2

Добавление этого в начало моего файла .js исправляет его:

var $ = django.jQuery;

Я не уверен, как удалить файл jquery.init.js, учитывая, что мой проект не содержит скриптов, которые используют $ для чего-то другого, кроме jQuery.

Ответ 3

Я решил эту проблему на этом пути, вы должны включить jquery.init.js(часто его jquery.init.js из admin) в этот файл добавить следующие строки:

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

и u имеют в целом jquery рабочего пространства и $. Для лучшего поиска кода я предпочитаю создавать свой собственный файл инициализации jquery в проекте.

Ответ 4

Используйте консоль Firebug или Web Inspector JS и введите $ и/или jQuery. Это самый простой способ узнать, правильно ли загружена библиотека. В маловероятном случае, что только jQuery определен, вы можете обернуть свой script в свою собственную область:

(function($){
    // your code here…
})(jQuery);

Если на консоли ничего не определено, проблема, скорее всего, будет связана с файлом, и я бы попробовал подход AndiDog, чтобы увидеть, есть ли что-нибудь загруженное вообще.

Ответ 5

В Firefox просмотрите исходный код страницы, затем нажмите ссылку "/media/js/jquery.min.js", чтобы узнать, загружена ли она. Скорее всего, вы получаете 404, потому что вы неправильно определили медиа-URL.

Вы также можете использовать сервер разработки для этой цели, он покажет вам все запросы и возвращает код состояния HTTP.

Ответ 6

В django одна из причин этой проблемы при использовании плагина import_export. В этом случае выполните следующие действия -

  1. Создайте папку в каталоге шаблонов администратора с именем import_export (templates/admin/import_export)
  2. Создайте там файл с именем base.html(templates/admin/import_export/base.html)
  3. введите приведенный ниже код base.html файл.

    {% extends "admin/import_export/base.html"%} {% load static%} {% block extrahead%} {{block.super}} static/admin/js/vendor/jquery/jquery.js static/admin/JS/jquery.init.js
    {% endblock%}

Ответ 7

Вероятно, вы забыли включить {{ form.media }} в свой шаблон.