Reputation: 4046
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
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
Reputation: 21
I believe the best way to accomplish what you want is to either:
Pass in a boolean responsive
flag and bind the window resize listener from within your plugin.
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
Reputation: 2405
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
});
});
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