我正在编写一个插件,我想保留我调用插件的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元素的引用
在这种情况下
_visible method
我想测试DOM现在是否在可见区域
return w.scrollTop() + w.height() >= $elem.offset().top;
我不知道如何跟踪方法中的DOM元素,好像有多个元素,那么我如何引用正确的DOM元素。
答案 0 :(得分:2)
您的var $elem = $(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);