I am trying to load three setting variables for bxSlider, based on the size of the window. I want the new settings to load dynamically when the browser is resized, not just on load. I have the below code that is setting the variables, I'm just struggling with making it play nicely with the bottom variable of mySlider, which is what is laoding the script upon resize.
Can anybody offer tips?
$(document).ready(function () {
/* Set variables for the maxSlides option */
var slidenumber,
width = $(window).width();
if (width < 768) {
slidenumber = 1;
} else if (width < 1024) {
slidenumber = 2;
} else {
slidenumber = 3;
}
$('.bxslider').bxSlider({
slideWidth: 5000,
minSlides: slidenumber,
maxSlides: slidenumber,
slideMargin: 50
});
var mySlider;
function tourLandingScript() {
mySlider.reloadSlider(slidenumber());
}
mySlider = $('.bxslider').bxSlider(slidenumber());
$(window).resize(tourLandingScript);
});
Best way to achieve this would be using CSS and media queries, so that you can hide or shrink slides without changing their number. However, if you need more complex behaviour that can't be achieved just with plain CSS, you'll need to write some javascript to it.
You need to listen to window's resize event and when it fires, recalculate required number of slides and if it changes, update slider using it's reloadSlider() method. The code could look somehow like this:
$(document).ready(function () {
var slideCount;
var mySlider;
// separate function to calculate required slide count
function calculateSlides() {
var width = $(window).width();
var slidenumber;
if (width < 768) {
slidenumber = 1;
} else if (width < 1024) {
slidenumber = 2;
} else {
slidenumber = 3;
}
return slidenumber;
}
// when page loads, we initialize the slider
slideCount = calculateSlides();
mySlider = $('.bxslider').bxSlider({
slideWidth: 5000,
minSlides: slideCount,
maxSlides: slideCount,
slideMargin: 50
});
// when we resize the window, just recalculate number of slides
// and if it has changed, reload the slider
$(window).resize(function() {
var newSlideCount = calculateSlides();
if (newSlideCount != slideCount) {
slideCount = newSlideCount;
mySlider.reloadSlider({
minSlides: newSlideCount,
maxSlides: newSlideCount
});
}
});
});
I also added some small optimization, so that browser won't rebuild whole slider component on every window resize (which triggers several times per second when resizing window by dragging its edge), but only in the moment when actual number of slides changes.
Hope this helps.
Thank you to Ondra Koupil for his help, however I was not able to get his solution to work exactly as required, I have ended up opting for an entirely new approach, which I'm sure could be pulled apart in order to optimise and is unlikely to be the most efficient option, but it works for me and hopefully can be of use to others.
The below solution is intended to be two entirely separate pieces of JS, which will not work if combined on one page. The intention is to load the relevant option (settings one/two) on the relevant page.
/* Settings one */
$(document).ready(function () {
var settings = function() {
var settings1 = { /* Desktop */
minSlides: 3,
maxSlides: 3,
moveSlides: 1,
slideWidth: 5000, /* Intentionally set to high value, bxslider will auto calculate */
slideMargin: 50
};
var settings2 = { /* Mobile */
minSlides: 1,
maxSlides: 1,
moveSlides: 1,
slideWidth: 2000 /* Intentionally set to high value, bxslider will auto calculate */
};
return ($(window).width()<1200) ? settings2 : settings1;
}
var mySlider;
function reloadonresize() {
mySlider.reloadSlider(settings());
}
mySlider = $('.bxslider').bxSlider(settings());
$(window).resize(reloadonresize);
});
/* End settings */
/* Settings two */
$(document).ready(function () {
var settings = function() {
var settings1 = { /* Desktop */
minSlides: 4,
maxSlides: 5,
moveSlides: 3,
slideWidth: 5000, /* Intentionally set to high value, bxslider will auto calculate */
slideMargin: 50
};
var settings2 = { /* Mobile */
minSlides: 2,
maxSlides: 2,
moveSlides: 1,
slideWidth: 2000 /* Intentionally set to high value, bxslider will auto calculate */
};
return ($(window).width()>=768) ? settings1 : settings2;
}
var mySlider;
function reloadonresize() {
mySlider.reloadSlider(settings());
}
mySlider = $('.bxslider').bxSlider(settings());
$(window).resize(reloadonresize);
});
/* End settings */
Related
like the title i'm using bxslider at my website, actually i'm using vertical thumbnail slide now, but the problem is, it's look ugly when at mobile width, so i want to change it like normal slider with arrow. can you help me how to do that? here is the things i want:
1. at normal using vertical thumb slide
2. when the width triggered at specify width, the thumb is hide (maybe display none at css)
3. Do destroyslider for stopping the vertical thumb slider and change it to normal slider with arrow
4. when the width is normal again, it will switch again to vertical thumb slider
ok here is my jquery:
var mainImage;
$(window).load(function() {
mainImage = $('.product-gallery').bxSlider({
infiniteLoop: false,
hideControlOnEnd: true,
pager: false,
controls: false,
auto: false,
minSlides: 1,
maxSlides: 1,
moveSlides: 1,
mode: 'fade',
adaptiveHeight: true
});
$('.product-gallery-thumbs ul').bxSlider({
infiniteLoop: false,
hideControlOnEnd: true,
pager: false,
auto: false,
minSlides: 4,
maxSlides: 4,
moveSlides: 1,
slideWidth: '100%',
mode: "#{options['product_thumbnail_direction']}",
slideMargin: 10,
onSliderLoad: function(currentIndex) {
$('.product-gallery-thumbs ul li').eq(0).addClass('active')
}
});
$('.product-gallery-thumbs ul li').each(function() {
$(this).click(function() {
$(this).addClass('active').siblings().removeClass('active');
mainImage.goToSlide($(this).index());
});
});
});
when do destroy :
mainImage.destroySlider();
here is normal slider with arrow:
mainImage.bxSlider({
mode: 'fade',
captions: true,
slideWidth: 600
});
UPDATE :
I try to did this, when do destroy is work, but when switching to normal arrow slider it doesn't work. Hope you guys can help me fix this
$(document).ready(function(){
setMaxWidth(767px);
mainImage.destroySlider();
function setMaxWidth(767px) {
mainImage.bxSlider({
mode: 'fade',
captions: true,
slideWidth: 600
});
})
bx.reloadSlider() Method
The method destroySlider() returns bxSlider as it was initially so don't use it if you want to change bxSlider after a reload, instead use reloadSlider(). Besides the obvious (reloading bxSlider), you can load a different set of options. Note: There are 2 Object Literals:
var cfgA = {...} and var cfgB = {...}
Each of them has key/value pairs (or properties) that are from the bxSlider API. When calling .bxSlider(), simply load one of configurations:
var bx = $('.bx').bxSlider(cfgA);
onSliderResize Callback
As far as slider plugins go, bxSlider isn't the most stable and it can get buggy as browsers update and bxSlider stagnates at v.4.2.12, but there's one thing bxSlider excels in is callbacks. I've written complex programs that are controlled by bxSlider callbacks because they are reliable and never break. In this demo onSliderResize call the function reloadBX(currentIndex). **Note: ** the absence of parenthesis on reloadBX():
onSliderResize: reloadBX
reloadBX(currentIndex)
This is the heart of the Demo. For demonstration purposes I've bound the function to a convenient button. When testing the Demo, you should expect the following by either clicking the RELOAD button, or resizing bxSlider:
Toggling between cfgA and cfgB
Relocates to the position index bxSlider was on before the reload.
Shifts images to adjust at reload to avoid images being stuck halfway.
Details commented in Demo
Demo
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>bxSlider Reload</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/bxslider/4.2.12/jquery.bxslider.css">
<style>
img {
margin: auto;
display: block;
max-width: 100%;
}
</style>
</head>
<body>
<button class='reload'>RELOAD</button>
<ul class='bx'>
<li>
<img src="https://i.imgur.com/DrEwPH0.jpg">
<img src="https://i.imgur.com/MEPxbq4.jpg">
</li>
<li>
<img src="https://i.imgur.com/6qGdA1e.gif">
</li>
<li>
<img src='https://i.imgur.com/DsM6J8U.gif'>
</li>
<li>
<img src="https://i.imgur.com/sbxyLKX.png">
</li>
<li>
<img src="https://i.imgur.com/DheohWR.gif">
</li>
</ul>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/bxslider/4.2.12/jquery.bxslider.min.js"></script>
<script>
// Cfg flag
var AB = 'A';
// Index counter
var idx = 0;
// cfgA
var cfgA = {
mode: 'horizontal',
slideWidth: 320,
adaptiveHeight: true,
onSliderResize: reloadBX
};
// cfgB
var cfgB = {
mode: 'fade',
captions: true,
slideWidth: 160,
adaptiveHeight: true,
onSliderResize: reloadBX
};
// Reference bxSlider instance
var bx = $('.bx').bxSlider(cfgA);
/*
Resize Callback
*/ // Called on resize event
function reloadBX(current) {
// Store current index
idx = current;
// Determine what configuration bx is in
if (AB === "A") {
/* if bx is in cfgA...
|| reload slider with cfgB
*/
bx.reloadSlider(cfgB);
// Shift all img to the left
$('img').css('transform', 'translateX(-25%)');
// Switch cfg flag to B
AB = "B";
// Otherwise...
} else {
// Reload slider with cfgA
bx.reloadSlider(cfgA);
// Shift all img to the right
$('img').css('transform', 'translateX(0)');
// Switch cfg flag to A
AB = "A";
}
// Go back to the index before reload
bx.goToSlide(idx);
}
// Added a reload button for convenient testing
$('.reload').click(function(e) {
// Get the current index and store it
idx = bx.getCurrentSlide();
/* Need to use the .call() function so that the context
|| is changed to bxSlider
*/
reloadBX.call(this, idx);
});
</script>
</body>
</html>
i am trying to make a flipbook with turn.js which is awesome.
the only problem i have is that i am trying to make it so in mobies it is single page display and in desktops double page display.
it does have the option to choose when creating the flipbook in javascript
display: 'single' or display: 'double'
i managed to achive changing that when you resize the window but with the onresize jwuery event but that makes it so it triggers only when you resize the window but if you dont it is always double page...so when the browser renders the page for mobile it is as defaul double page and not single
let me post my code here
// Create the flipbook
flipbook.turn({
// Magazine width
width: 922,
// Magazine height
height: 600,
// Duration in millisecond
duration: 1000,
// Enables gradients
gradients: true,
// Auto center this flipbook
autoCenter: true,
// Elevation from the edge of the flipbook when turning a page
elevation: 50,
// The number of pages
pages: 12,
// Events
when: {
turning: function(event, page, view) {
var book = $(this),
currentPage = book.turn('page'),
pages = book.turn('pages');
// Update the current URI
Hash.go('page/' + page).update();
// Show and hide navigation buttons
disableControls(page);
},
turned: function(event, page, view) {
disableControls(page);
$(this).turn('center');
$('#slider').slider('value', getViewNumber($(this), page));
if (page==1) {
$(this).turn('peel', 'br');
}
},
missing: function (event, pages) {
// Add pages that aren't in the magazine
for (var i = 0; i < pages.length; i++)
addPage(pages[i], $(this));
}
}
});
//change from single to double page
$(window).resize(function(){
var win = $(this); //this = window
if (win.width() >= 820) { flipbook.turn('display','double');}
else {
flipbook.turn('display','single');
}
});
i hope someone can help me fix this
To make the flipbook responsive for mobile, you can add the following code, which checks if the user agent of the navigator is mobile or not.
function checkMobile() {
return /iPhone|iPad|iPod|Android/i.test(navigator.userAgent);
}
And then use this in the resize of the window function.
if (!checkMobile()) { // not mobile
$('.flipbook').turn('display', 'double');
}
else {
$('.flipbook').turn('display', 'single');
}
You can use the above snippet after you have initialized the flipbook, to dynamically set the display (double, single) of the flipbook.
so hello everyone again, i managed to figure this out..
i changed the last code part from this
$(window).resize(function(){
var win = $(this); //this = window
if (win.width() >= 820) { flipbook.turn('display','double');}
else {
flipbook.turn('display','single');
}
});
to that
$(window).width(function(){
var win = $(this); //this = window
if (win.width() >= 820) { flipbook.turn('display','double');}
else {
flipbook.turn('display','single');
}
});
$(window).resize(function(){
var win = $(this); //this = window
if (win.width() >= 820) { flipbook.turn('display','double');}
else {
flipbook.turn('display','single');
}
});
it works fine both when you refresh the page and when you resize the window. I don't know if this the right way to do it but it seems to work perfectly fine
For mobile screens you have to change the screen width
here is tested and working code
if(window.innerWidth<768 && window.innerWidth >= 320) {
$('#flipbook').turn({
width:430,
height:650,
elevation:50,
inclination:50,
display: 'single',
autocenter:true,
acceleration: true,
gradients:true,
zoom:2,// you can change it as you desire
duration:50,
});
}
Here is what works for me on the mobile screen:
$('#flipbook').turn({
display: 'single',
acceleration: true,
gradients: true,
elevation:50,
when: {
turned: function(e, page) {
console.log('Current view: ', $(this).turn('view'));
}
}
});
I am working on a fade-in/out-effect-on-scroll on a web project.
On my js I have to set a certain value for the scroll position i. e. the offset to make the effect kick in.
The problem:
The offset value cannot be applied to all kinds of devices due to
different heights.
Questions (hierarchic):
How to make the static values dynamic and variable to the device
height/media queries?
How can you generally slim down the code?
How can I trigger an additional slide-slightly-from-right/left to the
effect?
Here is the code:
// ---### FOUNDATION FRAMEWORK ###---
$(document).foundation()
// ---### FADE FX ###---
// ## SECTION-01: fade out on scroll ##
$(window).scroll(function(){
// fade out content a
$(".j-fadeOut").css("opacity", 1 - $(window).scrollTop() / 470);// 470 should be variable
// ## SECTION-02: fade in/out on scroll bottom ##
var offset = $('.j-fadeOut-2').offset().top;
console.log('offset: '+offset);
console.log('window: '+$(window).scrollTop())
if($(window).scrollTop() > offset)
{
// fade out top part of content b
$(".j-fadeOut-2").css("opacity", 1-($(window).scrollTop() - offset)/520);// 520 should be variable
// fade in bottom part of content c
$(".j-fadeIn").css("opacity", 0 + ($(window).scrollTop() - offset)/ 1100);// 1100 should be variable
}
});
See here for JavaScript Media Queries
You can use window.matchMedia to perform media queries in JavaScript. Example:
var mediaQuery = window.matchMedia( "(min-width: 800px)" );
The result will be stored as a boolean in mediaQuery.matches, i.e.
if (mediaQuery.matches) {
// window width is at least 800px
} else {
// window width is less than 800px
}
You can use multiple of these to suit your different device widths. Using the standard Bootstrap buckets:
var sizes = ['1200px', '992px', '768px', '480px']; // standard Bootstrap breakpoints
var fadeOutAs = [470, 500, 530, 560]; // this corresponds to your content a fadeout variable. Modify as required per screen size
var fadeOutBs = [520, 530, 540, 550]; // content B fadeout
var fadeOutCs = [1100, 1200, 1300, 1400]; // content C fadeout
var fadeOutA = 0;
var fadeOutB = 0;
var fadeOutC = 0;
for (i = 0; i < sizes.length; i++) {
var mediaQuery = window.matchMedia( "(min-width: " + sizes[i] + ")" );
if (mediaQuery.matches) {
fadeOutA = fadeOutAs[i];
fadeOutB = fadeOutBs[i];
fadeOutC = fadeOutCs[i];
}
}
Hope this helps
I am using MasterSlider.js to make the carousal, I want to give it partialview on desktop and fillwidth view on tablet and mobile. I am trying to change it through detecting the window width but there is something wrong in my code.
<script type="text/javascript">
var slider = new MasterSlider();
slider.setup('masterslider' , {
width:700,
height:466,
space:5,
loop:true,
view:'fadeFlow',
layout:'partialview',
grabCursor:false,
centerControls:false,
autohide:false,
view:"fadeBasic",
});
slider.control('arrows' , {autohide:false});
if ($(window).width() < 1024) {
slider.setup('masterslider' , {
layout:'fillwidth',
grabCursor:false,
centerControls:false,
});
}
</script>
One more thing I am using fadeBasic option to make the previous and next image fade out by default it is applying opactiy 0.4, is there any way I make it 0.8. Opacity is applying on run time.
Just for reference I am using this slider:
http://www.mercurycustom.com/wp-content/uploads/2014/05/partialview/partialview3.html
Here is a running demo: http://codepen.io/anon/pen/dopNrM
Try this instead:
var slider = new MasterSlider();
slider.control('arrows');
if ($(window).width() < 1024) {
slider.setup('masterslider', {
layout: 'fillwidth',
grabCursor: false,
centerControls: false,
});
} else {
slider.setup('masterslider', {
width: 760,
height: 400,
space: 10,
loop: true,
view: 'fadeFlow',
layout: 'partialview',
});
}
I have a responsive slider which is supposed to show 1 item per slide at less than 600px width and 3 per slide above that. (as per http://flexslider.woothemes.com/dynamic-carousel-min-max.html) It works if window is loaded at those sizes, but does not work if window is resized (the items per slide don't change). I get an error "Cannot read property 'vars' of undefined" I've tried replacing "$" with jQuery in front of the var but the entire thing breaks at that point.
jQuery(window).load(function() {
// store the slider in a local variable
var $window = $(window),
flexslider;
// tiny helper function to add breakpoints
function getGridSize() {
return (window.innerWidth < 600) ? 1 :
(window.innerWidth < 900) ? 3 : 3;
}
$(function() {
SyntaxHighlighter.all();
});
jQuery('.flexslider').flexslider({
animation: "slide",
animationLoop: false,
itemWidth: 290,
itemMargin: 0,
minItems: getGridSize(), // use function to pull in initial value
maxItems: getGridSize() // use function to pull in initial value
});
// check grid size on resize event
jQuery(window).resize(function() {
var gridSize = getGridSize();
flexslider.vars.minItems = gridSize;
flexslider.vars.maxItems = gridSize;
});
});
}(document));