📜 ⬆️ ⬇️

Creating a jQuery plugin on the slider example

Often at work you have to embed sliders for scrolling images, blocks, etc. into the page. Having played enough with “alien” developments, which often have unnecessary and unnecessary functionality, it was decided to make my own bike and place it in the form of a jQuery plugin that would simply perform its horizontal slider function, and I would understand From and To.

This implementation does not claim to be perfect, since this is my first plugin, and the code may be terrible to me in time, but now everything seems fine and pretty bright to me and maybe it will be useful to someone.

First you need to study the rules for the design of the plugin for jQuery. I used the information on this link . Where did I find out that for files with jQuery plugins there is an agreement regarding their name - it must satisfy the format jquery.pluginName.js. Thus, the file with our plugin will need to be called jquery.lbslider.js - this is how I decided to name my slider, why lb is not clear to anyone except my beloved bride (you need to have at least some mystery). The plug-in code itself should have the following design (you can read more on the link above):

(function($){ jQuery.fn.pluginName = function(options){ //          . //        //    ,     //     options = $.extend({ param1: 'param1Value', //1 param2: 'param2Value' //2 }, options}; var make = function(){ //        }; return this.each(make); //  ,  pluginName    jQuery  }; })(jQuery); 

For a start, I decided to use such parameters in my implementation:
leftBtn - button for scrolling the slider to the left
rightBtn - button for scrolling the slider to the left
quantity - the number of visible elements on the page (sometimes they need only 1, and sometimes 3, 4 and more)
autoPlay - a boolean value indicating whether slider autoscrolling is necessary
autoPlayDelay - autoscroll delay
')
So, here are my default options:

 var options = $.extend({ leftBtn: 'leftBtn', rightBtn: 'rightBtn', quantity: 4, autoPlay: false, // true or false autoPlayDelay: 10 // delay in seconds }, options); 

We now proceed directly to the implementation. I decided that the html slider code will consist of a wrapper block, inside of which there will be buttons for scrolling and another block with a list <ul>, the elements of which will be messed up. First add some styles.

 var make = function() { $(this).css('overflow', 'hidden'); var el = $(this).children('ul'); el.css({ position: 'relative', left: '0' }); }; 

It was decided to make scrolling infinite, for this purpose we will duplicate several elements from the end at the beginning and several first elements at the end. A few are just the number of our visible elements on the page — the quantity parameter.

 var sliderFirst = el.children('li').slice(0, options.quantity); var tmp = ''; sliderFirst.each(function(){ tmp = tmp + '<li>' + $(this).html() + '</li>'; }); sliderFirst = tmp; var sliderLast = el.children('li').slice(-options.quantity); tmp = ''; sliderLast.each(function(){ tmp = tmp + '<li>' + $(this).html() + '</li>'; }); sliderLast = tmp; var elRealQuant = el.children('li').length; el.append(sliderFirst); el.prepend(sliderLast); 

If you noticed, we also retained the original number of elements in the elRealQuant variable - it will still be useful to us. Next, set the width of one element, it depends on the width of the whole block and the number of visible elements, also set the CSS property float: left. We learn the new number of all elements, after we have duplicated some of them and set the width of the entire list to be equal to the number of elements multiplied by the width of one element.

 var elWidth = el.width()/options.quantity; el.children('li').css({ float: 'left', width: elWidth }); var elQuant = el.children('li').length; el.width(elWidth * elQuant); el.css('left', '-' + elWidth * options.quantity + 'px'); 

We also moved the entire list to the left so that the duplicate elements added to the beginning were not visible when the page was loaded.

Now we will add functions to disable the scroll buttons for the time of the scrolling animation itself and their subsequent activation. It will be just an elementary addition / removal of the inactive class to the buttons, and by clicking on the buttons we will check if this class is present - do nothing. Of course, you can also set a separate style for such buttons.

 function disableButtons() { $('.' + options.leftBtn + ', .' + options.rightBtn).addClass('inactive'); } function enableButtons() { $('.' + options.leftBtn + ', .' + options.rightBtn).removeClass('inactive'); } 

Now we will write the functions themselves, which will work out by pressing the slider's scroll buttons:

 $('.' + options.leftBtn).click(function(event){ event.preventDefault(); if (!$(this).hasClass('inactive')) { disableButtons(); el.animate({left: '+=' + elWidth + 'px'}, 300, function(){ if ($(this).css('left') == '0px') {$(this).css('left', '-' + elWidth * elRealQuant + 'px');} enableButtons(); } ); } return false; }); 

This is the function for the left button. First, we disable the buttons, then, accordingly, we perform the scroll animation itself, and then we make the buttons active again. At the end of the animation, we check if the slider has reached the left edge - we move the whole block again to the right amount to the right - the user will not see it on the screen and again it will be possible to scroll left - and so on to infinity. The function for the right button will be similar, we will only scroll in the other direction and check if we scroll to the right edge - move it to the left.

It remains only to make autoscrolling, if one is set. In general, it will be just a periodic emulation of clicking on one of the buttons. Also, when you hover on the slider scrolling will stop, and when you remove the cursor - resumes.

 if (options.autoPlay) { function aPlay() { $('.' + options.rightBtn).click(); delId = setTimeout(aPlay, options.autoPlayDelay * 1000); } var delId = setTimeout(aPlay, options.autoPlayDelay * 1000); el.hover( function() { clearTimeout(delId); }, function() { delId = setTimeout(aPlay, options.autoPlayDelay * 1000); } ); } 

Well, that's all. You can now see the entire code of the plugin.

All code
 (function($){ $.fn.lbSlider = function(options) { var options = $.extend({ leftBtn: 'leftBtn', rightBtn: 'rightBtn', quantity: 3, autoPlay: false, // true or false autoPlayDelay: 10 // delay in seconds }, options); var make = function() { $(this).css('overflow', 'hidden'); var el = $(this).children('ul'); el.css({ position: 'relative', left: '0' }); var sliderFirst = el.children('li').slice(0, options.quantity); var tmp = ''; sliderFirst.each(function(){ tmp = tmp + '<li>' + $(this).html() + '</li>'; }); sliderFirst = tmp; var sliderLast = el.children('li').slice(-options.quantity); tmp = ''; sliderLast.each(function(){ tmp = tmp + '<li>' + $(this).html() + '</li>'; }); sliderLast = tmp; var elRealQuant = el.children('li').length; el.append(sliderFirst); el.prepend(sliderLast); var elWidth = el.width()/options.quantity; el.children('li').css({ float: 'left', width: elWidth }); var elQuant = el.children('li').length; el.width(elWidth * elQuant); el.css('left', '-' + elWidth * options.quantity + 'px'); function disableButtons() {$('.' + options.leftBtn + ', .' + options.rightBtn).addClass('inactive');} function enableButtons() {$('.' + options.leftBtn + ', .' + options.rightBtn).removeClass('inactive');} $('.' + options.leftBtn).click(function(event){ event.preventDefault(); if (!$(this).hasClass('inactive')) { disableButtons(); el.animate({left: '+=' + elWidth + 'px'}, 300, function(){ if ($(this).css('left') == '0px') {$(this).css('left', '-' + elWidth * elRealQuant + 'px');} enableButtons(); } ); } return false; }); $('.' + options.rightBtn).click(function(event){ event.preventDefault(); if (!$(this).hasClass('inactive')) { disableButtons(); el.animate({left: '-=' + elWidth + 'px'}, 300, function(){ if ($(this).css('left') == '-' + (elWidth * (options.quantity + elRealQuant)) + 'px') {$(this).css('left', '-' + elWidth * options.quantity + 'px');} enableButtons(); } ); } return false; }); if (options.autoPlay) { function aPlay() { $('.' + options.rightBtn).click(); delId = setTimeout(aPlay, options.autoPlayDelay * 1000); } var delId = setTimeout(aPlay, options.autoPlayDelay * 1000); el.hover( function() { clearTimeout(delId); }, function() { delId = setTimeout(aPlay, options.autoPlayDelay * 1000); } ); } }; return this.each(make); }; })(jQuery); 


And it is called quite simply. Like this:

 $('.slider').lbSlider({leftBtn: 'sa-left', rightBtn: 'sa-right', quantity: 3, autoPlay: true}); 

And of course DEMO

Not without flaws. For example, the width of the wrapping block is better set manually and so that it is completely divided by the number of visible elements, otherwise bugs arise with fractional values, reaching the edges.
Of course, you can still expand the functionality - for example, add some effects while scrolling itself, add the ability to scroll vertically, and of course remove the flaws, but for now it is enough.

UPD: Fixed a bug with the width, made small changes. The code is posted on github .

Source: https://habr.com/ru/post/153099/


All Articles