Какую цель выполняет генерация замыкания внутри функции $ (document) .ready ()? - PullRequest
4 голосов
/ 19 апреля 2011

Отладка одного из моих проектов Я заметил, что другой разработчик изменил функцию $(document).ready(), чтобы создать замыкание внутри себя.EG $(document).ready(function($) { }); Мне любопытно, как это сделать, а также как его использовать.

Примечание: При удалении $ из функции мой код снова работает.$(document).ready(function() { })

Оригинал / Фиксированный код

$(document).ready(function() {
    var id = //pull session variable from asp session (yuck)
    var img = $('.photoLink');

    $('.photoLink').click(function() {
        $(this).photoDialog({
            id: id,
            onClose: function() {
                img.attr('src', img.attr('src') + '&rand=' + (new Date()).getTime()); //prevent caching of image
            }
        });
    });
});

Модифицированный / неработающий код

$(document).ready(function($) {
    var id = //pull session variable from asp session (yuck)
    var img = $('.photoLink');

    $('.photoLink').click(function() {
        $(this).photoDialog({
            id: id,
            onClose: function() {
                img.attr('src', img.attr('src') + '&rand=' + (new Date()).getTime()); //prevent caching of image
            }
        });
    });
});

Модифицированный кодприведет к ошибкам в FireBug, утверждая, что пользовательская функция плагина, которую я вызывал, не существует.Я предполагаю, что это потому, что аргумент $ переопределяет или конфликтует с любой из функций jQuery, пытающихся его использовать.

Я действительно не понимаю, почему кто-то изменил это в текущем контекстеэто не имеет смысла, так как этот вызов плагина является единственным javascript на странице.

Может кто-нибудь объяснить мне, почему вы используете это и, возможно, пример его использования?

Править

Ниже приведен код для моего пользовательского плагина, я также изменил приведенные выше примеры, чтобы показать, как я его называю:

(function($) {
    var link = $('<link>');
    link.attr({
        type: 'text/css',
        rel: 'stylesheet',
        href: 'http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.7/themes/black-tie/jquery-ui.css'
    }).appendTo('head');

    var script = $('<script>');
    script.attr({
        type: 'text/javascript',
        src: 'https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.7/jquery-ui.min.js'
    }).appendTo('head');

    $.fn.photoDialog = function(options) {

        var defaults = {
            autoOpen: false,
            title: 'Photo Tool',
            minHeight: 560,
            minWidth: 540,
            url: '/photo_form.aspx',
            onClose: function(){}
        };
        var opts = $.extend(defaults, options);

        return this.each(function() {
            $this = $(this);
            that =$(this);
            var $dialog = $('<div>')
                .html('<iframe src="' + opts.url + '?sn=' + opts.id + '" width="' + (opts.minWidth - 20) + '" height="' + (opts.minHeight - 20) + '" style="border: none;" scrolling="no"></iframe>')
                .dialog({
                    autoOpen: opts.autoOpen,
                    title: opts.title,
                    minHeight: opts.minHeight,
                    minWidth: opts.minWidth,
                    modal: true,
                    close: function() {
                        opts.onClose.call(that);
                    }
                });

            $this.click(function() {
                $dialog.dialog('open');
                return false;
            });
        });
    };
})(jQuery);

Ответы [ 3 ]

3 голосов
/ 19 апреля 2011

Когда вы пишете плагин jQuery, для поддержки функции noConflict вы обычно делаете:

(function($) {
    // Plugin code...
})(jQuery);

Это позволяет вам использовать $ в качестве псевдонима для jQuery в коде плагина, независимо от настроек noConflict.

Возможно, другой разработчик добавил аргумент $ с помощью рефлекса.

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

Ваш код должен работать, даже если аргумент $ передан обработчику ready. Вы говорите, что пользовательская функция плагина, которую вы вызывали, больше не существует. Можете ли вы рассказать нам больше об этом кастомном плагине?

Я подозреваю, что $ меняется между вызовом на document.ready() и фактическим выполнением обработчика, и вы использовали это раньше, но больше не можете, поскольку исходный $ теперь передается обработчик.

2 голосов
/ 19 апреля 2011

jQuery передает ссылку на глобальный jQuery в готовые обработчики.Вот почему код должен быть написан таким образом, и на самом деле не должно быть с этим проблемой.Я подозреваю, что в этой истории есть нечто большее, чем показывает ваш вопрос.

edit - вот такая возможность: возможно, ваш плагин импортирует отдельный копия jQuery, и что она устанавливается на нее вместо вашей?Вы можете попробовать использовать такой инструмент, как TamperData или Chrome "Network" для разработчиков, чтобы просмотреть все HTTP-запросы и посмотреть, загружается ли jQuery дважды.В качестве альтернативы, поместите эту строку перед кодом "Broken":

$.banana = "yellow";

, а затем проверьте в своем коде обработчика, чтобы увидеть, есть ли у "$" свойство "banana".

Еслив этом случае разница будет в том, что ссылки в вашем "Broken" коде на "$" будут ссылками на копию jQuery, на которой не установлен плагин.Когда вы берете параметр «$», код может ссылаться на правильную, обновленную копию библиотеки.

2 голосов
/ 19 апреля 2011

первый аргумент, переданный функции внутри $(document).ready(..., является объектом jQuery.Шаблон, который вы видели, имеет смысл, только если у вас есть

// outside here, $ could be anything   

jQuery(document).ready(function($) {
    // $ inside here refers to jQuery
    $('.element').click(function() {
        //call custom plugin here
    });
});

. Это позволит псевдониму $ ссылаться на jQuery внутри функции для выполнения при загрузке DOM, даже если1007 * не ссылается на jQuery, а на что-то другое, например, на другую функцию библиотеки JavaScript.Но что у вас в вопросе, если window.$ ссылается на jQuery, то я ожидаю, что код будет работать без проблем.

...