0

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){


                $('#weblinks .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>
7
  • Can you maybe show a demo of the HTML, and what the constants are? (For example, will it always have a .container, .scrollDownBtn & .scrollUpBtn?) Commented Mar 11, 2011 at 19:57
  • sure - I've added that - the constants will be all of the HTML, and the methods used to calculate the scrollableAmt, viewAmt, and maxScroll. Commented Mar 11, 2011 at 20:03
  • @mheavers: What are the adjustable values you were looking to be different between scrollbars? (as in what parameters would you typically pass to this "Addon" that should be unique to scrollbar A versus *scrollbar B_?) Commented Mar 11, 2011 at 20:05
  • honestly - to keep things simple, the only thing I think I'd like to make unique right now is the div id that is passed to the function (from which other variables like scrollableAmt are derived. Commented Mar 11, 2011 at 20:43
  • @mheavers: Without a sandbox to test it in, I think I have it working, but you'll have to tell me. jsfiddle.net/kgUTu (missing the CSS/images you presumably have available to you) Commented Mar 11, 2011 at 21:22

3 Answers 3

1

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.

Sign up to request clarification or add additional context in comments.

Comments

1

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

Comments

1

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.

2 Comments

The only problem I see with this is that people could interact with multiple scrollers, which would throw off the variables like currentItem, because on one scroller, currentItem would be, say, 3, and on the other, it might be 4. Right?
Ah, yes, you might have a conflict on your variables in that case. What would be ideal is to then take the function and namespace it. If you correctly namespaced the function each time you used it then you would not encounter the problem. Additionally you could also keep an array that grows for each new instance.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.