Love Trivedi
Love Trivedi

Reputation: 4046

How to bind resize event in my custom plugin

I am creating a custom carousel and its working fine.

What I have:- I have a basic code which is working fine and carousel is also working fine in all screen and devices.

What I Want:- I have to reload after changing the resolution for changing the elements. I want that my plugin automatically load its setting for current screen resolution.

What I have tried:-

HTML

    <!doctype html>
<html>
<head>
 <meta charset="utf-8" />
 <link href="s.css" rel="stylesheet" />
 <script src="jquery.min.js"></script>
 <meta name="viewport" content="widht=device-width, initial-scale=1" />
 <script src="s.js"></script>
 <script>
 $(window).load(function(){
    $( "#divstretch" ).Lslider(
    {
        SlideCount:5,
        SlideMargin:20,
        SmSlideCount : 3,
        XsSlideCount : 2
    });
    });
 </script>
 </head>
 <body>
 <div class="Demo-Slider">

<ul id="divstretch">
<li><img target="" class="gall-img-big1" src="demo.jpg"></li>
<li><a rel="group1" href="" class="fancybox"><img target="" class="gall-img-big1" src="demo.jpg"></a></li>

<li><a rel="group1" href="" class="fancybox"><img target="" class="gall-img-big1" src="demo.jpg"></a></li>

<li><a rel="group1" href="" class="fancybox"><img target="" class="gall-img-big1" src="demo.jpg"></a></li>

<li><a rel="group1" href="" class="fancybox"><img target="" class="gall-img-big1" src="demo.jpg"></a></li>

<li><a rel="group1" href="" class="fancybox"><img target="" class="gall-img-big1" src="demo.jpg"></a></li>

<li><a rel="group1" href="" class="fancybox"><img target="" class="gall-img-big1" src="demo.jpg"></a></li>

<li><a rel="group1" href="" class="fancybox"><img target="" class="gall-img-big1" src="demo.jpg"></a></li>

<li><a rel="group1" href="" class="fancybox"><img target="" class="gall-img-big1" src="demo.jpg"></a></li>

<li><a rel="group1" href="" class="fancybox"><img target="" class="gall-img-big1" src="demo.jpg"></a></li>

<li><a rel="group1" href="" class="fancybox"><img target="" class="gall-img-big1" src="demo.jpg"></a></li>

<li><a rel="group1" href="" class="fancybox"><img target="" class="gall-img-big1" src="demo.jpg"></a></li>

</ul>
</div>
</div>
 </body>
 </html>

JS

(function ($) {
  var SlideCount = null;
  var SlideMargin = null;
  var SmSlideCount = null;
  var XsSlideCount = null;

  $.fn.Lslider = function (options) {
    var Lcontainer = this;
    var settings = $.extend({
      // These are the defaults.
      SlideCount: 4,
      SmSlideCount: 3,
      XsSlideCount: 2,
      SlideMargin: 10
    }, options);
    return this.each(function () {
      // We'll get back to this in a moment
      SlideCount = settings.SlideCount;
      SlideMargin = settings.SlideMargin;
      SmSlideCount = settings.SmSlideCount
      XsSlideCount = settings.XsSlideCount;
      SlideCount = Math.round(SlideCount);
      SmSlideCount = Math.round(SmSlideCount);
      XsSlideCount = Math.round(XsSlideCount);
      //paramiters
      var LcontanerID = $(Lcontainer).attr('id')
      var bigImgArray = $(Lcontainer).children();
      //appending required html
      $(Lcontainer).wrap('<div class="Lslider-Main"><div class="Lslider"></div></div>');
      var Pcontainer = $(Lcontainer).parent();
      var parentwidth = $(Pcontainer).width();
      var SlideWidth = null;

       //creating prev and next nav
      var MainContainer = $(Pcontainer).parent();
      $(MainContainer).prepend('<a class="Lslide-left">Prev</a>');
      $(MainContainer).append('<a class="Lslide-right">Next</a>');
      var next = $('.Lslide-right');
      var prev = $('.Lslide-left');

      //previous button 
      $(prev).click(function () {
        var stretch = $(Lcontainer).css('left');
        stretch = stretch.replace('px', '');
        stretch = parseInt(stretch);
        var incStretch = stretch + LIwidth + SlideMargin;
        if (stretch < 0) {
          $(Lcontainer).animate({
            left: incStretch
          });
        }
      });
       //next button

      $(next).click(function () {
        var stretch = $(Lcontainer).css('left');
        stretch = stretch.replace('px', '');
        stretch = stretch.replace('-', '');
        stretch = parseInt(stretch);
        var incStretch = stretch + LIwidth + SlideMargin;
        var strechWidth1 = $(Lcontainer).width();
        var strechWidth2 = $(Lcontainer).parent().width();
        var strechWidth = strechWidth1 - strechWidth2 - LIwidth;
        if (stretch <= strechWidth || stretch == '') {
          $(Lcontainer).animate({
            left: - incStretch
          });
        }
      });

      //-------------------------------------//

      var WSize = $(window).width();
      var WHeight = $(window).height(); 
      if (WSize < 481) {
        SlideWidth = parentwidth / XsSlideCount;
      } 
      else if (WSize < 768) {
        SlideWidth = parentwidth / SmSlideCount;
      } 
      else {
        SlideWidth = parentwidth / SlideCount;
      }
      $(bigImgArray).width(SlideWidth - SlideMargin);
      $(bigImgArray).css('margin-right', SlideMargin)

      //appending the height and width to containers
      var totleLI = $(bigImgArray).length;
      var LIwidth = $(bigImgArray).width();
      var totalWidth = LIwidth * totleLI;
      var totleHeight = $(bigImgArray).height();

      $(Lcontainer).width(totalWidth);
      $(Lcontainer).height(totleHeight);
      $(Pcontainer).height(totleHeight);

    });
  }
}) (jQuery);

css

.Demo-Slider{
    width:500px;
    margin:0px auto;
    max-width:100%;
    position:relative;
}
@media only screen and (max-width:768px){
.Demo-Slider{
width:100%;
}
}
.Lslider{
    position:relative;
    overflow:hidden;
}
.Lslider ul li{
    width:115px;
    margin-right:10px;
    float:left;
    display:block;
}
.Lslider ul li img{
    max-width:100%;
}
.Lslider ul {
    margin:0px;
    padding:0px;
    left:0px;
    right:0px;
    position: absolute;
}
.Lslider-Main .Lslide-left{
    position: absolute;
    left: -20px;
    top: 0px;
    bottom: 0px;
    margin: auto;
    height: 30px;
}
.Lslider-Main .Lslide-right{
    position: absolute;
    right: -20px;
    top: 0px;
    bottom: 0px;
    margin: auto;
    height: 30px;
}

Please review the code and give me your kind suggestion or solution.

Upvotes: 2

Views: 552

Answers (3)

Neel Shah
Neel Shah

Reputation: 791

You May use below code, instead of writing it for both load and resize event.

  $( window ).on('load resize',function() {
    $( "#divstretch" ).Lslider({
        SlideCount:5,
        SlideMargin:20,
        SmSlideCount : 3,
        XsSlideCount : 2
    });
 });

Upvotes: 0

Solomon Hawk
Solomon Hawk

Reputation: 21

I believe the best way to accomplish what you want is to either:

  1. Pass in a boolean responsive flag and bind the window resize listener from within your plugin.

  2. or make a public method that sets your slider to the proper size and then outside your plugin, bind it to window resize events.

I rewrote this plugin so that it has it's own constructor and methods which allows you to keep track of the Lslider instance and call it's public methods if you want to.

I should emphasize that this is not a complete solution. I've only tested this minimally to ensure it's not erroring. I also chose not to implement the next and prev methods, given the exact implementation depends on your markup and styles; instead I leave that as an exercise for you.

Pretty awful demo that simply show initialization and resize responsiveness. http://codepen.io/shawkdsn/pen/gbKMNK

Note: to use $.debounce, it must be defined, you can find an implementation here: http://benalman.com/projects/jquery-throttle-debounce-plugin/

(function($){

  var defaults = {
    slideCount    : 4,
    smSlideCount  : 3,
    xsSlideCount  : 2,
    slideMargin   : 10,
    responsive    : false, // whatever default you want
    debounceTime  : 50     // whatever default you want
  };

  // constructor
  var Lslider = function(el, options) {
    this.el = $(el);
    this.settings = $.extend({}, defaults, options);

    // save a reference to the Lslider instance
    this.el.data('Lslider', this);
    this.initialize();
  };

  Lslider.prototype.initialize = function() {
    this.setVars();
    this.wrapDom();
    this.createNavigation();
    this.bindEvents();
    this.setSize();
  };

  Lslider.prototype.setVars = function() {
    var s = this.settings;

    this.images = this.el.children();

    s.SlideCount = Math.round(s.slideCount);
    s.SmSlideCount = Math.round(s.smSlideCount);
    s.XsSlideCount = Math.round(s.xsSlideCount);
  };

  Lslider.prototype.wrapDom = function() {
    this.el.wrap('<div class="Lslider-Main"><div class="Lslider"></div></div>');
    this.elParent      = this.el.parent();
    this.elParentWidth = this.elParent.width();
    this.mainContainer = this.elParent.parent();
  };

  Lslider.prototype.createNavigation = function() {
    this.mainContainer.append('<a class="Lslide-next">Next</a>');
    this.mainContainer.prepend('<a class="Lslide-prev">Prev</a>');
    this.navNext = this.mainContainer.find('.Lslide-next');
    this.navPrev = this.mainContainer.find('.Lslide-prev');
  };

  Lslider.prototype.bindEvents = function() {
    this.mainContainer.on('click', '.Lslide-next', this.next.bind(this));
    this.mainContainer.on('click', '.Lslide-prev', this.prev.bind(this));

    if(this.settings.responsive) {
      $(window).on('resize',
        $.debounce(this.settings.debounceTime, this.setSize.bind(this))
      )
    }
  };

  Lslider.prototype.next = function() {
    // some code to show the next item
  };

  Lslider.prototype.prev = function() {
    // some code to show the previous item
  };

  Lslider.prototype.setSize = function() {
    var windowWidth  = $(window).width();
    var windowHeight = $(window).height();
    var imagesCount  = this.images.length;
    var imagesWidth  = this.images.width();
    var totalWidth   = imagesWidth * imagesCount;
    var totalHeight  = this.images.height();

    if (windowWidth < 481) {
      this.slideWidth = this.elParentWidth / this.settings.xsSlideCount;
    } 
    else if (windowWidth < 768) {
      this.slideWidth = this.elParentWidth / this.settings.smSlideCount;
    } 
    else {
      this.slideWidth = this.elParentWidth / this.slideCount;
    }

    this.images.each(function(i, el) {
      $(el).width(this.slideWidth - this.slideMargin);
      $(el).css('margin-right', this.slideMargin);
    }.bind(this));

    this.el.width(totalWidth).height(totalHeight);
    this.elParent.height(totalHeight);
  };

  $.fn.Lslider = function (options) {
    return this.each(function () {
      return new Lslider(this, options);
    })
  }
})(jQuery);

Then in your page, all you need to do is initialize the plugin and pass the responsive: true flag:

// grab a reference to the slider element
var $slider = $('#divstretch');

// instantiate the plugin, passing options
$slider.Lslider({
  slideCount    : 5,
  slideMargin   : 20,
  smSlideCount  : 3,
  xsSlideCount  : 2,
  responsive    : true,
  debounceTime  : 100
});

// If you'd prefer to wire up the listener outside your
// plugin then you could do something like the following,
// (without passing the responsive flag)
$(window).on('resize', $.debounce(100, function() {
  // use $.fn.data to get the Lslider instance and call it's `setSize` method
  $slider.data('Lslider').setSize();
}));

Even better would be to keep track of the sizes in an object and pass that in as an option. Just to demonstrate:

var sizes = {
  0:   1 // above 0px, show 1 item
  480: 2 // above 480px, show 2 items
  768: 3 // above 768px, show 3 items
}

// in `setSize`
var windowWidth = parseInt($(window).width(), 10);

// loop over the keys in the `sizes` object
var numberOfItems = Object.keys(this.settings.sizes).reduce(function(result, size) {
  // for each size, compare it to the window width
  // if the window is wider, save the item count
  if (windowWidth >= size) return result = sizes[size];
});

Edit: fixed a code typo

Upvotes: 2

kartikluke
kartikluke

Reputation: 2405

Method 1:

You can bind the function to the resize event. It'll run your function again every time there is a resize. This may cause problems if running the code twice on the item will cause problems.

$( window ).resize(function() {
  // Remove slider and redo
  $( "#divstretch" ).Lslider({
        SlideCount:5,
        SlideMargin:20,
        SmSlideCount : 3,
        XsSlideCount : 2
    });
});


Method 2:

Or you could wrap the code you'd like to rerun in the resize function. And it'll adjust automatically.

$( window ).resize(function() {
  ....
  //appending the height and width to containers
  var totleLI = $(bigImgArray).length;
  var LIwidth = $(bigImgArray).width();
  var totalWidth = LIwidth * totleLI;
  var totleHeight = $(bigImgArray).height();

  $(Lcontainer).width(totalWidth);
  $(Lcontainer).height(totleHeight);
  $(Pcontainer).height(totleHeight);
  ....
});


Just make sure to trigger the resize code once on load.

$(window).trigger('resize');

Upvotes: 4

Related Questions