Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/88.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何以面向对象的方式编写jquery插件_Javascript_Jquery_Jquery Plugins - Fatal编程技术网

Javascript 如何以面向对象的方式编写jquery插件

Javascript 如何以面向对象的方式编写jquery插件,javascript,jquery,jquery-plugins,Javascript,Jquery,Jquery Plugins,我已经编写了以下jquery插件。我试图做的是,当用户单击一个链接时,根据数据属性使相关的div显示:block base。但是这个插件不起作用。在过去的两天里,我一直在努力解决这个问题。但我失败了 我的HTML <div class="container1"> <a href="#" class="link1" data-link="a">asd</a> <div class="window1" data-window="a">

我已经编写了以下jquery插件。我试图做的是,当用户单击一个链接时,根据数据属性使相关的div显示:block base。但是这个插件不起作用。在过去的两天里,我一直在努力解决这个问题。但我失败了

我的HTML

<div class="container1">
    <a href="#" class="link1" data-link="a">asd</a>
    <div class="window1" data-window="a">
           asd         
    </div>
</div>

<hr>

<div class="container2">
    <a href="#" class="link2" data-link="b">asdf1</a>
    <a href="#" class="link2" data-link="c">asdf2</a>
    <a href="#" class="link2" data-link="d">asdf3</a>
    <div class="window2" data-window="b">
           asdf1         
    </div>
    <div class="window2" data-window="c">
           asdf2        
    </div>
    <div class="window2" data-window="d">
           asdf3         
    </div>
</div>

<script src="jquery-1.11.0.min.js"></script>
<script src="script.js"></script>

<script>

    $('.container1').myPlugin({
        link: $('.link1'),
        container : $('.window1')
    });
    $('.container2').myPlugin({
        link: $('.link2'),
        container : $('.window2')
    });

</script>
CSS


您需要使用
var
来确保您的变量都是局部变量,而不是全局变量

var MyPlugin = {
    // ...
};
另外,在
init
函数中,您正在执行以下操作:

$.fn.myPlugin.config = $.extend({}, $.fn.myPlugin.config, options);
这将覆盖默认选项
$.fn.myPlugin.config
。这意味着所有调用
myPlugin()
的元素将使用相同的配置。您只需要在一个实例上设置配置

this.config = $.extend({}, $.fn.myPlugin.config, options);
secondFunc: function (rezG) {
    return function(){
        var dataLinkId = $(this).data('link'),
            container = $(rezG.config.container).filter(function(){
                return $(this).data('window') == dataLinkId;
            });
        container.show();
    };
}
您的
secondFunc
没有对对象(
rezG
)实例的引用,因此无法访问配置。您需要将其传递到
secondFunc()
。一种方法是使用闭包捕获实例

this.config = $.extend({}, $.fn.myPlugin.config, options);
secondFunc: function (rezG) {
    return function(){
        var dataLinkId = $(this).data('link'),
            container = $(rezG.config.container).filter(function(){
                return $(this).data('window') == dataLinkId;
            });
        container.show();
    };
}
然后你就这样把它绑起来:

link.on('click', this.secondFunc(this));
请注意,在
secondFunc
中,您需要使用
config.container
(不仅仅是对象
config
),而且您的属性是
data window
,而不是
data section


更新的演示:

您需要使用
var
来确保您的变量都是局部变量,而不是全局变量

var MyPlugin = {
    // ...
};
另外,在
init
函数中,您正在执行以下操作:

$.fn.myPlugin.config = $.extend({}, $.fn.myPlugin.config, options);
这将覆盖默认选项
$.fn.myPlugin.config
。这意味着所有调用
myPlugin()
的元素将使用相同的配置。您只需要在一个实例上设置配置

this.config = $.extend({}, $.fn.myPlugin.config, options);
secondFunc: function (rezG) {
    return function(){
        var dataLinkId = $(this).data('link'),
            container = $(rezG.config.container).filter(function(){
                return $(this).data('window') == dataLinkId;
            });
        container.show();
    };
}
您的
secondFunc
没有对对象(
rezG
)实例的引用,因此无法访问配置。您需要将其传递到
secondFunc()
。一种方法是使用闭包捕获实例

this.config = $.extend({}, $.fn.myPlugin.config, options);
secondFunc: function (rezG) {
    return function(){
        var dataLinkId = $(this).data('link'),
            container = $(rezG.config.container).filter(function(){
                return $(this).data('window') == dataLinkId;
            });
        container.show();
    };
}
然后你就这样把它绑起来:

link.on('click', this.secondFunc(this));
请注意,在
secondFunc
中,您需要使用
config.container
(不仅仅是对象
config
),而且您的属性是
data window
,而不是
data section


更新的演示:

您需要使用
var
来确保您的变量都是局部变量,而不是全局变量

var MyPlugin = {
    // ...
};
另外,在
init
函数中,您正在执行以下操作:

$.fn.myPlugin.config = $.extend({}, $.fn.myPlugin.config, options);
这将覆盖默认选项
$.fn.myPlugin.config
。这意味着所有调用
myPlugin()
的元素将使用相同的配置。您只需要在一个实例上设置配置

this.config = $.extend({}, $.fn.myPlugin.config, options);
secondFunc: function (rezG) {
    return function(){
        var dataLinkId = $(this).data('link'),
            container = $(rezG.config.container).filter(function(){
                return $(this).data('window') == dataLinkId;
            });
        container.show();
    };
}
您的
secondFunc
没有对对象(
rezG
)实例的引用,因此无法访问配置。您需要将其传递到
secondFunc()
。一种方法是使用闭包捕获实例

this.config = $.extend({}, $.fn.myPlugin.config, options);
secondFunc: function (rezG) {
    return function(){
        var dataLinkId = $(this).data('link'),
            container = $(rezG.config.container).filter(function(){
                return $(this).data('window') == dataLinkId;
            });
        container.show();
    };
}
然后你就这样把它绑起来:

link.on('click', this.secondFunc(this));
请注意,在
secondFunc
中,您需要使用
config.container
(不仅仅是对象
config
),而且您的属性是
data window
,而不是
data section


更新的演示:

您需要使用
var
来确保您的变量都是局部变量,而不是全局变量

var MyPlugin = {
    // ...
};
另外,在
init
函数中,您正在执行以下操作:

$.fn.myPlugin.config = $.extend({}, $.fn.myPlugin.config, options);
这将覆盖默认选项
$.fn.myPlugin.config
。这意味着所有调用
myPlugin()
的元素将使用相同的配置。您只需要在一个实例上设置配置

this.config = $.extend({}, $.fn.myPlugin.config, options);
secondFunc: function (rezG) {
    return function(){
        var dataLinkId = $(this).data('link'),
            container = $(rezG.config.container).filter(function(){
                return $(this).data('window') == dataLinkId;
            });
        container.show();
    };
}
您的
secondFunc
没有对对象(
rezG
)实例的引用,因此无法访问配置。您需要将其传递到
secondFunc()
。一种方法是使用闭包捕获实例

this.config = $.extend({}, $.fn.myPlugin.config, options);
secondFunc: function (rezG) {
    return function(){
        var dataLinkId = $(this).data('link'),
            container = $(rezG.config.container).filter(function(){
                return $(this).data('window') == dataLinkId;
            });
        container.show();
    };
}
然后你就这样把它绑起来:

link.on('click', this.secondFunc(this));
请注意,在
secondFunc
中,您需要使用
config.container
(不仅仅是对象
config
),而且您的属性是
data window
,而不是
data section


更新的演示:

您的插件可以像

(function ($, window, document, undefind) {
$.fn.myPlugin = function(options) {
    // When $(stuff).myPlugin(...) is called
    // this keyword inside of myPlugin function is referencing a set 
    // of elements plugin was called upon
    // e.g. for call like $('.container1').myPlugin();
    // this keyword will reference all elements selected by 
    // $('.container1') not jquery wrapped, 
    // in general it can be a any number.
   return this.each(function pluginImplementation () {
       // Here we iterate over the set, and for each element in the set
       // we do some pretty standard click 
       var container = $(this);
       // I use 'click.myPlugin' event instead just 'click' ale to later on
       // do $(..).off('click.myPlugin') to remove only handlers that were 
       // attached by plugin (a good practice)
       container.on('click.myPlugin', options.linkSelector, function(){               
           var dataLinkId = $(this).data('link');
           container.find('[data-window="' + dataLinkId + '"]').toggle();
       })
   });
};
})(jQuery, window, document);

然而,上面的代码可能有一个问题
luginImplementation()
函数是在每次迭代中创建的,如果该函数的主体更复杂,那么它将是一团混乱。这就是为什么最好在外部创建
pluginImplementation()

(function ($, window, document, undefind) {
    // Notice that pluginImplementation () now accepts parameters
    // They make it possible for pluginImplementation to know which
    // elements it's working with

    function pluginImplementation (container, options) {
        container.on('click.myPlugin', options.linkSelector, function(){               
            var dataLinkId = $(this).data('link');
            container.find('[data-window="' + dataLinkId + '"]').toggle();
        })
    }

    $.fn.myPlugin = function(options) {
        return this.each(function () {
            pluginImplementation($(this), options);
        });
    };
})(jQuery, window, document);

这种分离可能还不够好。你可能希望你的插件更加面向对象,而不是什么。因此,你可以像这样做:

(function ($, window, document, undefind) {
    // For that purpose we create a class
    // That describes behavior that our plugin provides
    // 
    function MyPlugin(container, options) {
        this.container = container;
        this.options = options;

        // To the topic of maintainability 
        // This could be parametrised as an option at plugin instantiation
        this.eventName = 'click.myPlugin';
    }

    MyPlugin.prototype.attachClickHandlers = function() {
        var self = this;
        // This gets a little messy with all the thises vs selfs and a 
        // noname function wrapping the handler.
        // The point is to preserve this keyword reference 
        // inside of clickHandler method.
        // If I would have just self.clickHandler as a handler there
        // this keyword inside of self.clickHandler would reference to 
        // whatever $(...).on binds handlers to i.e. triggering element.
        // I need this keyword inside of self.clickHandler to point to 
        // "current" instance of MyPlugin, that's why I have wrapping 
        // function. It just lets me call clickHandler in the right context.
        // clickHandler method also needs to know what link is being clicked
        // so we pass that in as parameter.
        self.container.on(self.eventName, 
                          self.options.linkSelector, 
                          function() {
            self.clickHandler($(this));
        })
    }

    MyPlugin.prototype.clickHandler = function(clickedLink) {
        var dataLinkId = clickedLink.data('link');
        this.container.find('[data-window="' + dataLinkId + '"]').toggle();
    }

    $.fn.myPlugin = function(options) {
        return this.each(function () {
            var pluginInstance = new MyPlugin($(this), options);
            pluginInstance.attachClickHandlers();
        });
    };        
})(jQuery, window, document);
在这个实现中,MyPlugin是一个类(在javascript意义上是单词class),它使您能够以其行为方式处理每个特定点。并介绍各种面向对象的特性


你的插件可以简单到

(function ($, window, document, undefind) {
$.fn.myPlugin = function(options) {
    // When $(stuff).myPlugin(...) is called
    // this keyword inside of myPlugin function is referencing a set 
    // of elements plugin was called upon
    // e.g. for call like $('.container1').myPlugin();
    // this keyword will reference all elements selected by 
    // $('.container1') not jquery wrapped, 
    // in general it can be a any number.
   return this.each(function pluginImplementation () {
       // Here we iterate over the set, and for each element in the set
       // we do some pretty standard click 
       var container = $(this);
       // I use 'click.myPlugin' event instead just 'click' ale to later on
       // do $(..).off('click.myPlugin') to remove only handlers that were 
       // attached by plugin (a good practice)
       container.on('click.myPlugin', options.linkSelector, function(){               
           var dataLinkId = $(this).data('link');
           container.find('[data-window="' + dataLinkId + '"]').toggle();
       })
   });
};
})(jQuery, window, document);

然而,上面的代码可能有一个问题
luginImplementation()
函数是在每次迭代中创建的,如果该函数的主体更复杂,那么它将是一团混乱。这就是为什么最好在外部创建
pluginImplementation()

(function ($, window, document, undefind) {
    // Notice that pluginImplementation () now accepts parameters
    // They make it possible for pluginImplementation to know which
    // elements it's working with

    function pluginImplementation (container, options) {
        container.on('click.myPlugin', options.linkSelector, function(){               
            var dataLinkId = $(this).data('link');
            container.find('[data-window="' + dataLinkId + '"]').toggle();
        })
    }

    $.fn.myPlugin = function(options) {
        return this.each(function () {
            pluginImplementation($(this), options);
        });
    };
})(jQuery, window, document);

这种分离可能还不够好。你可能希望你的插件更加面向对象,而不是什么。因此,你可以像这样做:

(function ($, window, document, undefind) {
    // For that purpose we create a class
    // That describes behavior that our plugin provides
    // 
    function MyPlugin(container, options) {
        this.container = container;
        this.options = options;

        // To the topic of maintainability 
        // This could be parametrised as an option at plugin instantiation
        this.eventName = 'click.myPlugin';
    }

    MyPlugin.prototype.attachClickHandlers = function() {
        var self = this;
        // This gets a little messy with all the thises vs selfs and a 
        // noname function wrapping the handler.
        // The point is to preserve this keyword reference 
        // inside of clickHandler method.
        // If I would have just self.clickHandler as a handler there
        // this keyword inside of self.clickHandler would reference to 
        // whatever $(...).on binds handlers to i.e. triggering element.
        // I need this keyword inside of self.clickHandler to point to 
        // "current" instance of MyPlugin, that's why I have wrapping 
        // function. It just lets me call clickHandler in the right context.
        // clickHandler method also needs to know what link is being clicked
        // so we pass that in as parameter.
        self.container.on(self.eventName, 
                          self.options.linkSelector, 
                          function() {
            self.clickHandler($(this));
        })
    }

    MyPlugin.prototype.clickHandler = function(clickedLink) {
        var dataLinkId = clickedLink.data('link');
        this.container.find('[data-window="' + dataLinkId + '"]').toggle();
    }

    $.fn.myPlugin = function(options) {
        return this.each(function () {
            var pluginInstance = new MyPlugin($(this), options);
            pluginInstance.attachClickHandlers();
        });
    };        
})(jQuery, window, document);
在这个实现中,MyPlugin是一个类(在javascript意义上是单词class),它使您能够以其行为方式处理每个特定点。并介绍各种面向对象的特性


你的插件可以简单到

(function ($, window, document, undefind) {
$.fn.myPlugin = function(options) {
    // When $(stuff).myPlugin(...) is called
    // this keyword inside of myPlugin function is referencing a set 
    // of elements plugin was called upon
    // e.g. for call like $('.container1').myPlugin();
    // this keyword will reference all elements selected by 
    // $('.container1') not jquery wrapped, 
    // in general it can be a any number.
   return this.each(function pluginImplementation () {
       // Here we iterate over the set, and for each element in the set
       // we do some pretty standard click 
       var container = $(this);
       // I use 'click.myPlugin' event instead just 'click' ale to later on
       // do $(..).off('click.myPlugin') to remove only handlers that were 
       // attached by plugin (a good practice)
       container.on('click.myPlugin', options.linkSelector, function(){               
           var dataLinkId = $(this).data('link');
           container.find('[data-window="' + dataLinkId + '"]').toggle();
       })
   });
};
})(jQuery, window, document);

然而,上面的代码可能有一个问题
luginImplementation()
函数是在每次迭代中创建的,如果该函数的主体更复杂,那么它将是一团混乱。这就是为什么最好在外部创建
pluginImplementation()

(function ($, window, document, undefind) {
    // Notice that pluginImplementation () now accepts parameters
    // They make it possible for pluginImplementation to know which
    // elements it's working with

    function pluginImplementation (container, options) {
        container.on('click.myPlugin', options.linkSelector, function(){               
            var dataLinkId = $(this).data('link');
            container.find('[data-window="' + dataLinkId + '"]').toggle();
        })
    }

    $.fn.myPlugin = function(options) {
        return this.each(function () {
            pluginImplementation($(this), options);
        });
    };
})(jQuery, window, document);

这种分离可能还不够好。你可能希望你的插件更加面向对象,而不是什么。因此,你可以像这样做:

(function ($, window, document, undefind) {
    // For that purpose we create a class
    // That describes behavior that our plugin provides
    // 
    function MyPlugin(container, options) {
        this.container = container;
        this.options = options;

        // To the topic of maintainability 
        // This could be parametrised as an option at plugin instantiation
        this.eventName = 'click.myPlugin';
    }

    MyPlugin.prototype.attachClickHandlers = function() {
        var self = this;
        // This gets a little messy with all the thises vs selfs and a 
        // noname function wrapping the handler.
        // The point is to preserve this keyword reference 
        // inside of clickHandler method.
        // If I would have just self.clickHandler as a handler there
        // this keyword inside of self.clickHandler would reference to 
        // whatever $(...).on binds handlers to i.e. triggering element.
        // I need this keyword inside of self.clickHandler to point to 
        // "current" instance of MyPlugin, that's why I have wrapping 
        // function. It just lets me call clickHandler in the right context.
        // clickHandler method also needs to know what link is being clicked
        // so we pass that in as parameter.
        self.container.on(self.eventName, 
                          self.options.linkSelector, 
                          function() {
            self.clickHandler($(this));
        })
    }

    MyPlugin.prototype.clickHandler = function(clickedLink) {
        var dataLinkId = clickedLink.data('link');
        this.container.find('[data-window="' + dataLinkId + '"]').toggle();
    }

    $.fn.myPlugin = function(options) {
        return this.each(function () {
            var pluginInstance = new MyPlugin($(this), options);
            pluginInstance.attachClickHandlers();
        });
    };        
})(jQuery, window, document);
在这个实现中,MyPlugin