【问题标题】:jquery plugin does not work on multiple elements - options overwrittenjquery 插件不适用于多个元素 - 选项被覆盖
【发布时间】:2012-03-17 01:33:14
【问题描述】:

我尝试制作我的第一个 jquery 插件(一个灯箱)。它以我想要的方式在单个元素上工作,但如果我使用多个元素,它会覆盖我的选项。

这是我当前的代码。由于布局,它似乎不适用于 jsFiddle。

http://jsfiddle.net/BjwCm/

您可以在此处下载带有工作(失败)示例的代码:

http://frumbert.org/files/frumbox.zip

我可以看到,当我绑定到第二个对象但不知道我做错了什么时,我以某种方式覆盖了默认对象中的选项。我试过移动点击绑定的地方,但不能让它工作。

【问题讨论】:

    标签: jquery jquery-plugins boilerplate


    【解决方案1】:

    $this,在最外层的闭包中声明并贯穿始终,代表 FrumBox 实例化的最后一个元素。

    就我个人而言,我不会尝试按原样修复代码。而是采用jQuery's "Best Practices" pattern。这是我基于给定示例的模板:

    (function($){
        // **********************************
        // ***** Start: Private Members *****
        var pluginName = 'xxxxx';
        // ***** Fin: Private Members *****
        // ********************************
    
        // *********************************
        // ***** Start: Public Methods *****
        var methods = {
            init : function(options) {
                //"this" is a jquery object on which this plugin has been invoked.
                return this.each(function(index){
                    var $this = $(this);
                    var data = $this.data(pluginName);
                    // If the plugin hasn't been initialized yet
                    if (!data){
                        var settings = {
                        };
                        if(options) { $.extend(true, settings, options); }
    
                        $this.data(pluginName, {
                            target : $this,
                            settings: settings
                        });
                    }
                });
            },
            myMethod_1 : function(){.....},
            myMethod_2 : function(){.....}
        };
        // ***** Fin: Public Methods *****
        // *******************************
    
        // *****************************
        // ***** Start: Supervisor *****
        $.fn[pluginName] = function( method ) {
            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 in jQuery.' + pluginName );
            }
        };
        // ***** Fin: Supervisor *****
        // ***************************
    })( jQuery );
    

    注意事项:

    • 根据需要添加更多私有成员和方法。
    • 公共成员(方法)具有特权(他们可以访问私有成员)。
    • 为保持可链接性,请务必在每个方法中采用return this.each(function(index){...}) 模式,返回特定值的方法除外。
    • 可以说,使用这种模式(和其他模式)进行开发的最困难的方面是了解this 在每种情况下所指的内容。保持理智。
    • 准备好使用 javascript Function.call()Function.apply 方法。确保你理解它们。
    • 主管乍一看很难理解,但不一定是 修改的。这是一段很酷的代码。
    • 使用$(selector).pluginNmae()$(selector).pluginNmae(options) 在DOM 元素上实例化插件,其中options 是对象文字“映射”。
    • 使用$(selector).pluginNmae('methodName', ...) 调用已初始化的 DOM 元素上的方法
    • 可以在selected answer here 中找到这种模式的一个示例(包括指向小提琴的链接)。

    【讨论】:

    • 是的,我知道你是对的。我刚刚得出同样的结论。我知道 $this 的范围必须“太高”,因此它会覆盖以前的设置,因此搞砸了。你的主管还回答了我下一个关于正确调用不同方法的问题。我真的不确定什么是“最佳实践”方法(似乎经常争论) - 我看过一些:github.com/zenorocha/jquery-plugin-patterns 并以我认为相当不错的一个作为起点。我想这就是让我搞砸的原因。
    • @frumbert 当然没有明确的插件模式,但有些比其他更好。感谢github链接,我之前没有找到它。当我有时间时,我会浏览一下,看看我能学到什么。我喜欢我上面发布的模式,因为我相信它,但也因为我已经习惯了。作为一个保守派,我可能会在可预见的未来坚持下去。
    • 嗯,我更新的代码 - jsfiddle.net/BjwCm/1 - 有问题。我的选择器是 $(".external-links a");调用 open 将在与特定实例不匹配的最后一个“a”上触发。
    • 抱歉一直纠缠于此,但如果你看看这个新版本 - jsfiddle.net/BjwCm/2 - 我发现它在使用具有多个匹配项的选择器时执行“每个”选项.所以我必须在调用者函数中执行每个/绑定(参见测试用例代码,小提琴底部)。这可行,但似乎“混乱”,并且似乎否定了插件内部对 each 的需要。您的插件模板中内部 each 的预期用途是什么?
    • 在方法中,return $(this).each(function(){...}) 遍历使用 $(selector).pluginName('methodName') 进行的 jQuery 选择。选择不会被记住,因为每次调用 $(selector).pluginName('methodName') 时选择器都可能不同。
    猜你喜欢
    • 1970-01-01
    • 2020-11-17
    • 1970-01-01
    • 1970-01-01
    • 2015-09-16
    • 2021-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多