jquery prototype for a commonly used function
I'm not too experienced in JQuery beyond standard api functionality, but I have a number of scrollers on my page which all use the same code, only they each have a few of their own settings (for example, separate heights and scroll limits, and current number of times they have been scrolled). I want to be able to use the code over and over again, but with each reference receiving its own set of variables. I think that prototypes are what I'm after, but I can't quite wrap my head around the examples I've seen of this. This is my scroller code:
$(document).ready(function() {
var scrollAmt = 50; //distance in pixels;
var scrollableAmt = $('#weblinks .container').outerHeight();
var viewAmt = $('#weblinks').outerHeight();
var maxScroll = Math.ceil((scrollableAmt-viewAmt) / scrollAmt);
var currentItem = 0;
function setScrollButtons(scrollRef,scrollAmount){
}
$("#weblinks .scrollDownBtn").click(function(){
if (currentItem <= maxScroll){
$('#web开发者_Go百科links .container:not(:animated)').animate({'top' : '-='+ scrollAmt + ''},500,function(){
currentItem++
});
} else {
currentItem = 0;
$('#weblinks .container:not(:animated)').animate({'top' : currentItem},500);
}
});
$("#weblinks .scrollUpBtn").click(function(){
if (currentItem > 0){
$('#weblinks .container:not(:animated)').animate({'top' : '+='+ scrollAmt + ''},500,function(){
currentItem--;
});
} else {
$('#weblinks .container:not(:animated)').animate({'top' : currentItem},500);
}
});
});
So essentially what I'd want to do is create a function or class, I guess, which accomplishes all of the above code, but be able to pass it a div reference to take the place of #weblinks, and maybe pass it a scroll amount, and multiple instances of this functionality be able to exist on the same page together. Anybody have any advice about the best way to go about this?
EDIT: I've added the HTML that will always exist for each scroller.
<div id="weblinks" class="scrollbar_container">
<div class="customScrollBox">
<div class="container">
<div class="content">
</div>
</div>
<a class="scrollUpBtn" href="javascript:void(0);"></a> <a class="scrollDownBtn" href="javascript:void(0);"></a>
</div>
</div>
My Bid:
(function($){
$.fn.extend({
customScroller: function(options){
return this.each(function(i,e){
var container = $(e).find('.container'),
content = $(e).find('.content'),
scrollUpBtn = $(e).find('.scrollUpBtn'),
scrollDownBtn = $(e).find('.scrollDownBtn');
var self = $(e);
var o = $.extend({}, $.fn.customScroller.defaults, options);
o.scrollableAmt = container.outerHeight();
o.viewAmt = self.outerHeight();
o.maxScroll = Math.ceil((o.scrollableAmt - o.viewAmt) / o.scrollAmt);
scrollDownBtn.click(function(){
console.log('DOWN -- current: '+o.currentItem);
if (o.currentItem <= o.maxScroll){
container.filter(':not(:animated)').animate({
top: '-='+o.scrollAmt
},500,function(){
o.currentItem++;
});
}else{
o.currentItem = 0;
container.filter(':not(:animated)').animate({
top: o.currentItem
},500);
}
});
scrollUpBtn.click(function(){
console.log('UP -- current: '+o.currentItem);
if (o.currentItem > 0){
container.filter(':not(:animated)').animate({
top: '+='+o.scrollAmt
},500,function(){
o.currentItem--;
});
}else{
container.filter(':not(:animated)').animate({
top: o.currentItem
},500);
}
});
});
}
});
$.fn.customScroller.defaults = {
scrollAmt: 50,
scrollableAmt: 0,
viewAmt: 0,
maxScroll: 0,
currentItem: 0
};
})(jQuery);
$('#weblinks').customScroller();
To answer your question, I use extend in a couple of places: one for the options, and the other for jQuery addon ability.
$.fn.extend
tells jQuery this is extending its functionality.$.extend({},$.fn.customScroller.defaults, option);
allows you to call.customScroller({ scrollAmount: 10 })
and change the behavior of the scroll.
any other questions, please just ask.
This is a good candidate for jQuery plugin you can create for yourself. Of course if you want to spend some time and learn this principle :)
How to develop a jQuery plugin for some details of what and how jQuery plugins do
You could pretty simply refactor it in the case that all div's will have a sub container class. Something like:
function scrollExample(divId) {
var scrollAmt = 50; //distance in pixels;
var scrollableAmt = $(divId + ' .container').outerHeight();
var viewAmt = $(divId).outerHeight();
var maxScroll = Math.ceil((scrollableAmt-viewAmt) / scrollAmt);
var currentItem = 0;
function setScrollButtons(scrollRef,scrollAmount){
}
$(divId + " .scrollDownBtn").click(function(){
if (currentItem <= maxScroll){
$(divId + ' .container:not(:animated)').animate({'top' : '-='+ scrollAmt + ''},500,function(){
currentItem++
});
} else {
currentItem = 0;
$(divId + ' .container:not(:animated)').animate({'top' : currentItem},500);
}
});
$(divId + " .scrollUpBtn").click(function(){
if (currentItem > 0){
$(divId + ' .container:not(:animated)').animate({'top' : '+='+ scrollAmt + ''},500,function(){
currentItem--;
});
} else {
$(divId + ' .container:not(:animated)').animate({'top' : currentItem},500);
}
});
});
Then call it with something like:
$(document).ready(function() {
scrollExample('#webLinks');
}
If you had the actual reference to the object it would be slightly different, but still follow a similar principle.
精彩评论