1
\$\begingroup\$

InstaSlider is a lightweight jQuery image slider / carousel plugin that populates content from an Instagram hashtag.

After searching for a similar solution for one of my own projects with no luck I decided there might be others who would benefit from this.

It is the bare minimum function at the moment so there will be more features and updates added soon!

Demo

(function($, window, document, undefined){

    var InstaSlider = {

        init: function(options, container){

            var self = this;
                self.container = container,
                self.$container = $(container),
                self.current = 0, // Set current to 0 on initialise
                self.imgWidth = self.$container.width(); // img width will be the same as the container

                self.options = $.extend({}, $.fn.instaSlider.options, options);

                self.imgLength = self.options.limit;

                this.createSlider(); // Create the slider

                self.sliderUL = self.$container.find('.instaslider-wrapper ul');
        },

        createSlider: function(){
            // create the slider
            var slider = this.$container.append('<div class="instaslider-wrapper"><ul></ul></div>');

            this.createNav();
            this.createSlides();

        },

        createNav: function() {

            var self = this;
            // create the navigation for the slider
            var buttonPrev = '<button class="' + this.options.prevClass + '" data-direction="prev">Prev</button>',
                buttonNext = '<button class="' + this.options.nextClass + '" data-direction="next">Next</button>',
                nav = '<div class="instaslider-nav">' + buttonPrev + buttonNext + '</div>';

            // append it to the container
            this.$container.append(nav);

            // when a button is clicked set current
            this.$container.find('button').on('click', function(){
                self.setCurrent( $(this).data('direction') );
                self.transition();
            });

        },

        fetch: function() {

            // Set the endpoint

            var endpoint = 'https://api.instagram.com/v1/tags/' + this.options.hash + '/media/recent?client_id=' + this.options.clientID;   

            //fetch images from instagram

            return $.ajax({
                url: endpoint,
                data: {},
                dataType: 'jsonp',
                type:'GET'
            });

        },

        createSlides: function() {
            // create the slides
            var self = this,
                container = this.$container,
                sliderUL = container.find('.instaslider-wrapper ul');           

            self.fetch().done(function(results){

                // Limit the amount of results
                results = self.limit( results.data, self.options.limit );
                // loop over results create a slider for each one.
                self.slides = $.map(results, function(obj, i){
                    var img = '<li><img src="' + results[i].images.standard_resolution.url + '" /></li>';
                    sliderUL.append(img);
                });

            });

            self.fetch().fail(function(){
                sliderUL.remove();
                container.html('<div class="error"><p>Sorry,<br /> Could not fetch images at this time.</p></div>');
            })

        },

        setCurrent: function(direction) {
            // set the current slide and handle direction here
            var self = this;
            var pos = self.current;
            pos += ( ~~(direction === 'next') || -1);
            self.current = ( pos < 0 ) ? self.imgLength -1 : pos % self.imgLength;
            return pos;
        },

        transition: function() {
            // handle animation and slide transition here
            var self = this;

            self.sliderUL.stop().animate({
                'margin-left': -( this.current * this.imgWidth )
            });
        },

        limit: function(obj, count) {
            return obj.slice( 0, count );
        },

    };

    $.fn.instaSlider = function(options){
        return this.each(function(){
            var instaSlider = Object.create( InstaSlider );
            instaSlider.init(options, this);
            $.data(this, 'instaSlider', instaSlider);
        });
    };

    /*----------------------------------------------------------------
        Default Options
    ----------------------------------------------------------------*/

    $.fn.instaSlider.options = {

        // Default Options
        clientID: null,
        hash:'photooftheday',
        prevClass: 'prev',
        nextClass: 'next',
        limit: 5,
    }

})(jQuery, window, document, undefined);
\$\endgroup\$
3
\$\begingroup\$

I think you'd really benefit looking at either jQuery UI's widget factory or (my preference) using some boilerplate such as jQuery Boilerplate.

Other than that, in no particular order:

  1. $.fn.instaSlider.options = {... I've never seen anyone do this and I'm not sure what you're trying to achieve with it. Just have your defaults as a local variable within the IIFE and close over it.
  2. You're creating a new endpoint variable on every call of fetch(). Create it once in init e.g. self.endPoint = 'theUrl'
  3. self.imgLength = self.options.limit; this is pointless.
  4. I don't think that you should have prev and next classes as an option, just name them uniquely e.g. 'instaSlider-next' - it's the kind of customisation that most people would never want or need.
  5. createNav has no need for all 3 variables, just create one and build the entire html string and append it.
  6. Don't use <br /> tags for spacing - people will come and eat you.

I'd say you're on the right track - just a bit of polishing here and there.

\$\endgroup\$
  • \$\begingroup\$ Thanks! Those are some really useful pointers. I was debating leaving the next/prev classes as fixed but I know in the past i've used plugins that had similar names and so I thought i'd just leave that in incase. \$\endgroup\$ – Chris May 16 '13 at 19:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.