【问题标题】:jQuery Plugin: Make jQuery Variable Accessible Across all Plugin FunctionsjQuery 插件:使 jQuery 变量可在所有插件函数中访问
【发布时间】:2012-06-18 06:00:45
【问题描述】:

我在 jQuery 插件中缺少一些基本的变量范围。以下是一个 jQuery 插件存根(主要基于 jQuery.com 文档)。

我想让变量($testtest)可用于插件中的所有函数。

在下面的示例代码中,变量 test 按预期将 'hello' 写入控制台。

但是,变量$test 将 jQuery() 写入控制台。

问题: (a) 为什么$test 不将 jQuery(div#test) 写入控制台? (b) 使 jQuery 变量(或任何其他变量)在所有函数中可用的最佳实践是什么。例如类似于 .net 类中的类级别变量。

(function ($) {

var settings = {
};

var methods = {
    init: function (options) { if (options) { $.extend(settings, options); } return init(this, settings); }
};

$.fn.scopetest = function (method) {
    // Method calling logic
    if (methods[method]) {
        return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
    } else if (typeof method === 'object' || !method) {
        return methods.init.apply(this, arguments);
    } else {
        $.error('Method ' + method + ' does not exist on jQuery plugin');
    }
};

var $test = $('#test');
var test = 'hello';

var init = function (object, settings) {
    return object.each(function () {

        console.log($test);
        console.log(test);
    });
}

})(jQuery);

【问题讨论】:

    标签: jquery scope


    【解决方案1】:

    尝试各种选项:

    (function ($) {
    
    var options = {
            option1: "some_value",
            option2: "another_value",
            ...
        }
    var settings = {
        };
    

    从你的函数中这样引用:

    var self = this;
    alert( self.options.option1 );
    

    或者:

    var self = this,
        o = self.options;
    alert( o.option1);
    

    还可以查看 Jquery widget factory plugin layout,它与你的很接近,但我更喜欢它。

    (function( $, window) {
    
        $.widget("widge_name", $.widget, {
    
            options: {
            ...
            },
            init: function(param_1, param_2) {
            ...
            },
            _create: function() {
            ...
            },
            some_function_A: function(param3, param4) {
            ...
            }
            some_function_B: function(param3, param4) {
            var self = this;
            // run some_function_A 
            self.some_function_A("foo","bar");
            }
      });
    }) (jQuery,this);
    

    这样你就可以像上面一样使用 self 调用其他函数。

    【讨论】:

    • 我在这里看到了完全相同的行为。如果我这样定义选项: var options = { test1: 'test', test2: $('#test') };我可以访问 options.test1 和 options.test2(无需定义 self),但 test2 上的 console.log 会写入 jQuery()。
    • 嗯。尝试不返回 object.each(function () {}?只是控制台。
    • 我在这里仍然缺少一些基本的东西。再次查看后,我看到选项(和所有功能)都在小部件声明中。这是否意味着在所有函数中使用变量的唯一方法是重构插件?
    • 删除“return object.each(function () {”会导致相同的行为。
    【解决方案2】:
    • 为什么 $test 不将 jQuery(div#test) 写入控制台?

      因为,在 DOM 中没有 ID 为 test 的元素。所以,jQuery 返回空集合jQuery()

    • 让 jQuery 变量(或任何其他变量)在所有函数中可用的最佳实践是什么?

      我不确定最佳实践,但如果我必须使变量可全局访问,我会将变量与window 对象相关联。喜欢,

      window.$test = $('#test');
      window.test = 'Hello';

    并使用window 对象(例如:alert(window.$test);)或简单地使用变量名alert($test); 访问它们

    【讨论】:

    • 该元素确实存在。如果 console.log($('#test'));语句被移到 init 函数内,返回预期的输出。这里的目的不是在所有插件中声明一个全局变量,而是为插件创建一个私有变量(在插件内的所有函数中可用)。
    【解决方案3】:

    有趣的是,保留 var $test 语句但将赋值移至 init 函数似乎可行。因此,除非它在函数内部,否则使用 $ 似乎存在问题。将使用此作为解决方法,直到找到更好的解决方案。

    (function ($) {
    
    var settings = {
    };
    
    var methods = {
        init: function (options) { if (options) { $.extend(settings, options); } return init(this, settings); }
    };
    
    $.fn.scopetest = function (method) {
    
        // Method calling logic
        if (methods[method]) {
            return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
        } else if (typeof method === 'object' || !method) {
            return methods.init.apply(this, arguments);
        } else {
            $.error('Method ' + method + ' does not exist on jQuery plugin');
        }
    };
    
    var $test;
    var test;
    
    var init = function (object, settings) {
    
        return object.each(function () {
    
            $test = $('#test');
            test = 'hello';
            testfunc();
        });
    }
    
    var testfunc = function () {
        console.log($test);
        console.log(test);
    }
    
    })(jQuery);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-24
      相关资源
      最近更新 更多