Jquery 在插件中保留DOM元素的引用

Jquery 在插件中保留DOM元素的引用,jquery,jquery-plugins,Jquery,Jquery Plugins,我正在编写一个插件,其中我希望保留我调用插件的DOM元素的引用 代码看起来像 ;(function ( $, window, document, undefined ) { "use strict"; var $elem = $(this); var methods = { /** * __constructor method * @param {} user defined options

我正在编写一个插件,其中我希望保留我调用插件的DOM元素的引用

代码看起来像

;(function ( $, window, document, undefined ) {
    "use strict";

    var $elem = $(this);    

    var methods = {
        /**
         * __constructor method
         * @param {} user defined options
         */
         init: function( options ) {

            $elem = (this);

            /**
             * save options
             */
            options = $.extend( true, {}, $.fn.xyz.defaults, options );
            $elem.data('options', options);

            console.info($elem);
         },

        /**
         * Attachs window's scroll event
         */
        attach: function(  ) {
            var w = $(window);
            w.on( 'scroll', methods._load);
            return this;
        },


        detach: function() {
            var w = $(window);  
            w.off( 'scroll', methods._load);    
        },

        /**
         * Tests it the DIV is within viewport
         */
        _visible: function() {
            var w = $(window);  

            return w.scrollTop() + w.height() >= $elem.offset().top;
        },


        _load: function() {
            if( methods._visible() ) {
                console.info("load data");      
                methods.detach();
            }
        }


    }





    $.fn.xyz = function() {
        var _this = $(this);


        if(!_this[0]) return _this;  // stop here if the container does not exist

        methods.init.apply( _this, arguments );
        return methods.attach.apply( _this );

    }

    $.fn.xyz.defaults = {
        onSuccess: false,
        onFailure: false,
        data: {}
    }

})( jQuery, window, document );
我的问题是,在这些方法中,我希望引用使用此插件的DOM元素

在这种情况下

_可视方法

我想测试DOM现在是否在可见区域中

return w.scrollTop() + w.height() >= $elem.offset().top;
我不知道如何在方法中跟踪DOM元素,就好像有多个元素一样,那么如何引用正确的DOM元素。

Your
var$elem=$(这)
无法可靠地工作,因为它的作用域是整个插件的作用域,而不是它的任何特定调用

相反,请确保:

  • 方法的编写方式使得它们的
    this
    是对其执行操作的jQuery集合
  • 方法的调用/传递方式是指定其上下文this。为此,您需要熟悉,并且
以下是经过修改的代码,并附有进一步的改进(未经测试):

;(function ($, window, document, undefined) {
    "use strict";

    var pluginName = 'xyz'; //avoids potential repetition throughout the plugin

    // `defaults` can be defined here.
    // Like `methods` it will remain available due to closure.
    var defaults = {
        onSuccess: false,
        onFailure: false,
        data: {}
    };

    var methods = {
        /**
         * __constructor method
         * @param {} user defined options
         */
        init: function( options ) {
            // Each element in the collection should get its own *independent* options.
            // This immunises every element against future destruction or changes made to other elements' options.
            return this.each(function() {
                $( this ).data( pluginName+'Data', $.extend( true, {}, defaults, options ) );
            });
         },
        /**
         * Attaches window.onScroll handler(s)
         */
        attach: function() {
            // The attached handler is now subject to `.bind()` and, as a function in its own right, can't be removed with `$(window).off( 'scroll', methods._load);`.
            // A reference to each bound instance needs to be kept to allow it to be detached independently of any others.
            // The most convenient scope for each element to store a reference to *its* scroll handler is the data object established in init().
            return this.each(function() {
                var $this = $( this );
                var data = $this.data( pluginName+'Data' );
                data.scrollHandler = methods._load.bind( $this );
                $(window).on( 'scroll', data.scrollHandler );
            });
        },
        /**
         * Detaches window.onScroll handler(s)
         */
        detach: function() {
            return this.each(function() {
                var scrollHandler = $( this ).data( pluginName+'Data' ).scrollHandler;
                if( scrollHandler ) {
                    $( window ).off( 'scroll', scrollHandler );
                }
            });
        },
        /**
         * Tests it the DIV is within viewport
         */
        _visible: function() {
            var w = $( window );
            return w.scrollTop() + w.height() >= this.offset().top;
        },
        _load: function() {
            return this.each(function() {
                var $this = $( this );
                if( methods._visible.call( $this ) ) {
                    methods.detach.call( $this );
                }
            });
        }
    }
    $.fn[pluginName] = function() {
        var _this = this; // `this` is already a jQuery collection object, so no need for $(this).
        if(!_this[0]) return _this;  // stop here if the collection is empty
        methods.init.apply(_this, arguments);
        return methods.attach.call(_this);
    }
})(jQuery, window, document);