jquery 插件无法访问插件定义中引用的对象

发布于 2024-12-19 04:59:43 字数 1477 浏览 0 评论 0原文

我正在尝试编写一个插件,它可以对我选择的 dom 元素中某些输入字段的任何更改做出反应。

我的插件定义如下:

(function($){

    var methods = {
        init : function( options ) { 
            console.log(this.obj);
            var inputs = $('input', this.obj);
            $.each(inputs, function(i, domElement){
                $(this.obj).premiumUpdatable('addEvent', $(domElement));
            })

        },
        addEvent: function(element){
            $(element).bind('change',function(){
                console.log($(element).val());
            })
        }
    };

    $.fn.premiumUpdatable = function( method ) {

        return this.each(function(){
            var obj = $(this);
            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.premiumUpdatable' );
            }    
        });
    };
})(jQuery);

然后我像这样调用我的插件:

$('div.updatable').premiumUpdatable();

问题是,当我在定义的方法之一中尝试 console.log(this.obj) 时,我总是得不到定义。我希望获得我在插件定义中所做的引用,obj = $(this); ...我希望获得 $(this) 元素。

我需要将此插件应用于页面上的多个 dom 元素,但如果我无法获取 dom 元素的引用...我无法真正分辨哪个是哪个....

任何帮助将不胜感激。 ..

PS:我可能没有问正确的问题,因为我对在 jquery 中开发插件还很陌生,但这个问题似乎真的困扰着我,我无法克服它。

I am trying to write a plugin that would react to any changes on some input fields within a dom element that i choose.

my plugin definition is as follows:

(function($){

    var methods = {
        init : function( options ) { 
            console.log(this.obj);
            var inputs = $('input', this.obj);
            $.each(inputs, function(i, domElement){
                $(this.obj).premiumUpdatable('addEvent', $(domElement));
            })

        },
        addEvent: function(element){
            $(element).bind('change',function(){
                console.log($(element).val());
            })
        }
    };

    $.fn.premiumUpdatable = function( method ) {

        return this.each(function(){
            var obj = $(this);
            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.premiumUpdatable' );
            }    
        });
    };
})(jQuery);

Then I call my plugin like:

$('div.updatable').premiumUpdatable();

Problem is that when i try console.log(this.obj) in one of the methods defined i always get undefined. I wish to get the reference that i made in the definition of the plugin, obj = $(this); ...i wish to get the $(this) element.

I need this plugin applied to a number of dom elements on the page but if i can't get the reference to the dom element ...i can't really tell which is which....

Any help would be greatly appreciated...

PS: I may not be asking the right questions as I am still new to developing plugins in jquery but this problem seems to really bug me and I can't overcome it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

暮年 2024-12-26 04:59:44

我将您的代码包装到迄今为止我能找到的最可靠的 jquery 插件结构中。这也将解决您无法访问插件范围内的对象的问题

<!DOCTYPE html>
<html>
<head>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
    <script>
        (function($){
            $.premiumUpdatable = function(el, options){
                // set a reference to the class instance
                var base = this,
                    // store all inputs for reuse
                    inputs;

                // store the options in base.o
                base.o = $.extend({},$.premiumUpdatable.defaultOptions, options);
                // set a reference to the jquery object
                base.$el = $(el);
                // set a reference to the DOMNode
                base.el = el;

                /**
                 * @public
                 * This function can be accessed from outside the plugin scope with
                 * $('.premium').data('premiumUpdatable').publicFunction();
                 */
                this.publicFunction = function(){};

                var initInputs = function(){
                    inputs = $( 'input', base.$el.attr('id') ).each( function( i, domElement ){
                        $( domElement ).bind( 'change', function(){
                            console.log( 'input ' + $( this ).attr('id') + ' changed to: ', $( this ).val() );
                        });
                    });
                };

                /**
                 * @private
                 * self-executing constructor
                 */
                (function init(){
                    initInputs();
                })();
            };
            // defining the default options here makes it posible to change them globaly with
            // $.premiumUpdatable.defaultOption.myValue = 'value'
            // or
            // $.premiumUpdatable.defaultOption = { myValue:'value' }
            // before the first initialisation for the objects to come
            $.premiumUpdatable.defaultOptions = {};
            $.fn.premiumUpdatable = function(options){
                return this.each(function( index, element ){
                    // prevents a second initialisation of the object if data('premiumUpdatable') is already set
                    if ( undefined == $( element ).data('premiumUpdatable') ) {
                        // stores a referenze to the PluginClass, to that your able to access its public function from outside with
                        // $('.premium').data('premiumUpdatable').publicFunction();
                        $( element ).data('premiumUpdatable', new $.premiumUpdatable( element, options));
                    }
                });
            };
        })(jQuery);

        $( document ).ready( function(){
           $('.premium').premiumUpdatable();
        });
    </script>
</head>
<body>
   <div class="premium">
       <form>
           <input id="inputText" type="text" value="" /><br />
           <input id="inputPassword" type="password" value="" /><br />
           <input id="inputCheckbox" type="checkbox" value="something checked" /><br />
           <input id="inputRadio" type="radio" value="1" />
       </form>
   </div>
</body>
</html>

I wrapped your Code into the most solid plugin structure for jquery plugins I could find so far. This will also sort out your problem not being able to access the object inside your plugin scope

<!DOCTYPE html>
<html>
<head>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
    <script>
        (function($){
            $.premiumUpdatable = function(el, options){
                // set a reference to the class instance
                var base = this,
                    // store all inputs for reuse
                    inputs;

                // store the options in base.o
                base.o = $.extend({},$.premiumUpdatable.defaultOptions, options);
                // set a reference to the jquery object
                base.$el = $(el);
                // set a reference to the DOMNode
                base.el = el;

                /**
                 * @public
                 * This function can be accessed from outside the plugin scope with
                 * $('.premium').data('premiumUpdatable').publicFunction();
                 */
                this.publicFunction = function(){};

                var initInputs = function(){
                    inputs = $( 'input', base.$el.attr('id') ).each( function( i, domElement ){
                        $( domElement ).bind( 'change', function(){
                            console.log( 'input ' + $( this ).attr('id') + ' changed to: ', $( this ).val() );
                        });
                    });
                };

                /**
                 * @private
                 * self-executing constructor
                 */
                (function init(){
                    initInputs();
                })();
            };
            // defining the default options here makes it posible to change them globaly with
            // $.premiumUpdatable.defaultOption.myValue = 'value'
            // or
            // $.premiumUpdatable.defaultOption = { myValue:'value' }
            // before the first initialisation for the objects to come
            $.premiumUpdatable.defaultOptions = {};
            $.fn.premiumUpdatable = function(options){
                return this.each(function( index, element ){
                    // prevents a second initialisation of the object if data('premiumUpdatable') is already set
                    if ( undefined == $( element ).data('premiumUpdatable') ) {
                        // stores a referenze to the PluginClass, to that your able to access its public function from outside with
                        // $('.premium').data('premiumUpdatable').publicFunction();
                        $( element ).data('premiumUpdatable', new $.premiumUpdatable( element, options));
                    }
                });
            };
        })(jQuery);

        $( document ).ready( function(){
           $('.premium').premiumUpdatable();
        });
    </script>
</head>
<body>
   <div class="premium">
       <form>
           <input id="inputText" type="text" value="" /><br />
           <input id="inputPassword" type="password" value="" /><br />
           <input id="inputCheckbox" type="checkbox" value="something checked" /><br />
           <input id="inputRadio" type="radio" value="1" />
       </form>
   </div>
</body>
</html>
旧梦荧光笔 2024-12-26 04:59:44

当您执行此操作来调用 init() 方法时:

return methods.init.apply( this, arguments );

this 是当前 DOM 元素,并且您显然期望在 init() 方法中this 是您的插件实例。

另一个问题是您的 obj 属性是在 .each() 回调中声明的,因此它在 init() 中不可见无论如何方法。

这里的链接提出了开发 jquery 插件的基本结构:
jQuery 插件样板


作为插件开发的补充,这里有一些关于 javascript 中“this”关键字的链接。真正理解它非常重要,我认为在开发时不要陷入难以理解的情况:

this 关键字< /a>
JavaScript 中的“this”是什么?
更好的 JavaScript – 这是什么?

When you do this to call the init() method:

return methods.init.apply( this, arguments );

this is the current DOM element, and you obviously expect in the init() method this to be your plugin instance.

Another problem is that your obj property is declared withint the .each() callback, so it won't be visible in the init() method anyway.

The link here proposes a base structure for developing jquery plugins:
jQuery plugin boilerplate


Complementary to the plugin development, here are some links about the 'this' keyword in javascript. It's pretty important to really understand it I think to not end up in uncomprehensible situations while developing:

The this keyword
What is ‘this’ in JavaScript?
BETTER JAVASCRIPT–WHAT IS THIS?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文