How to remove slick slide on mobile? - javascript

I'm using the awesome Slick slide on a project.
The problem is: I have a carousel with 5 divs inside. 4 images and a video.
On mobile (< 768px) I want the slider to show only the images, not the video.
I tried to hide the video div by css but that's not working.
Any ideas on how to do this? Anyone had this need before?

Look at the «Filtering» demo at the Slick's documentation. Let's use it to solve the issue.
Set breakpoints that you need, using the responsive option.
Catch the breakpoint event and read the activeBreakpoint property of the carousel. Notabene: when the screen width is greater than the last of the breakpoints, this property returns null.
Call slickFilter and slickUnfilter methods:
slickFilter
Argument filter: selector or function
Filters slides using jQuery .filter syntax
slickUnfilter
Removes applied filter
Beware of an infinite loop: these methods cause a re-initialization of the slider, during which the breakpoint event again occurs (unless the breakpoint is null).
Call these methods during initialization too. Don’t forget to define the init handler before the initialization.
Check the result: https://codepen.io/glebkema/pen/NaGGzv
Slides with the .hide-on-mobile class become hidden when the screen width is 700px or less.
var breakpointMobile = 700,
isChanging = false,
isFiltered = false;
$('#breakpointMobile').text( breakpointMobile );
$('#myCarousel').on('init breakpoint', function(event, slick){ /** 2. and 5. **/
if ( ! isChanging ) { /** 4. **/
$('#breakpointValue').text( String(slick.activeBreakpoint) );
isChanging = true;
if ( slick.activeBreakpoint && slick.activeBreakpoint <= breakpointMobile) {
if ( ! isFiltered ) {
slick.slickFilter(':not(.hide-on-mobile)'); /** 3. **/
isFiltered = true;
}
} else {
if ( isFiltered ) {
slick.slickUnfilter();
isFiltered = false;
}
}
isChanging = false;
}
}).slick({
autoplay: true,
dots: true,
responsive: [ /** 1. **/
{ breakpoint: 500 },
{ breakpoint: 700 },
{ breakpoint: 900 }
]
});
body { /** Decorations **/
font-family: 'Open Sans', sans-serif;
}
.my-carousel img {
width: 100%;
}
.my-carousel .slick-next {
right: 15px;
}
.my-carousel .slick-prev {
left: 15px;
z-index: 1;
}
<h3>Slides 2, 3 and 5 become hidden when the screen width is <span id="breakpointMobile"></span>px or less</h3>
<p>Active breakpoint is <b id="breakpointValue"></b>. Try to resize the workspace.</p>
<div id="myCarousel" class="my-carousel">
<div>
<img src="https://via.placeholder.com/900x300/c69/f9c/?text=1" alt="">
</div>
<div class="hide-on-mobile">
<img src="https://via.placeholder.com/900x300/9c6/cf9/?text=2" alt="">
</div>
<div class="hide-on-mobile">
<img src="https://via.placeholder.com/900x300/69c/9cf/?text=3" alt="">
</div>
<div>
<img src="https://via.placeholder.com/900x300/c33/f66/?text=4" alt="">
</div>
<div class="hide-on-mobile">
<img src="https://via.placeholder.com/900x300/099/3cc/?text=5" alt="">
</div>
<div>
<img src="https://via.placeholder.com/900x300/f93/fc6/?text=6" alt="">
</div>
</div>
<link rel="stylesheet" href="//cdn.jsdelivr.net/gh/kenwheeler/slick#1.8.0/slick/slick.min.css">
<link rel="stylesheet" href="//cdn.jsdelivr.net/gh/kenwheeler/slick#1.8.0/slick/slick-theme.css">
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="//cdn.jsdelivr.net/gh/kenwheeler/slick#1.8.0/slick/slick.min.js"></script>

Slick has the method slickRemove (you have to scroll down a bit):
Remove slide by index. If removeBefore is set true, remove slide preceding index, or the first slide if no index is specified. If removeBefore is set to false, remove the slide following index, or the last slide if no index is set.
I would just call this method and remove the slide with the video if your current screen size is lower than 768px.

You can unslick at a given breakpoint now by adding:
settings: "unslick"
instead of a settings object
To remove slick slider on mobile view add above code snippet to responsive breakpoint like this
$('.responsive').slick({
dots: true,
infinite: false,
speed: 300,
slidesToShow: 4,
slidesToScroll: 4,
responsive: [
{
breakpoint: 1024,
settings: {
slidesToShow: 3,
slidesToScroll: 3,
infinite: true,
dots: true
}
},
{
breakpoint: 600,
settings: "unslick"
}
// You can unslick at a given breakpoint now by adding:
// settings: "unslick"
// instead of a settings object
]
});

Related

Embla Carousel - select inner text

I have a carousel built using Embla Carousel (embla-carousel-react).
The elements within the carousel contain an image and some text. The text is not selectable, but I would like it to be.
When I set draggable: false, I can select the text inside the carousel, but now I can no longer scroll the carousel to the next slide.
Is there a way I can have both - select and copy text with a mouse click and drag, and swipe to the next scroll with a more pronounced swipe or scroll gesture?
const EmblaCarousel = ({ children, nextScroll, recordCurrentSlide }) => {
const { height } = useWindowDimensions()
const [viewportRef, embla] = useEmblaCarousel({
axis: "y",
skipSnaps: false,
startIndex: 0,
draggable: true,
dragFree: false,
slidesToScroll: 1,
loop: true,
},
[WheelGesturesPlugin()]);
return (
<div className="embla">
<div className="embla__viewport" ref={viewportRef}>
<div className="embla__container">
{children}
</div>
</div>
<style jsx>{`
:global(.embla__container) {
height: ${height};
}
`}</style>
</div>
);
};
Thanks!
I'm the creator of Embla Carousel and at the time of writing, what you want to achieve isn't possible. This is because Embla calls event.preventDefault() on touch and mouse events when the carousel has draggable: true set.
If you want to discuss this design choice and suggest changes, you may create a new discussion.

Slick carousel adaptive height not working when showing 2 slides

I am building a website with some sliders and using Slick for that. Usually, in regards to the slides when I am showing 1 slide at a time the adaptive height works but when showing 2 slides at the same time it doesn't work. Here is the issue replicated in a JSFiddle.
Here is the JavaScript:
var options = {
slidesToShow: 2,
slidesToScroll: 2,
dots: true,
arrows: false,
dotsClass: 'slick-dots slick-dots-black',
adaptiveHeight: true,
};
$('.slider').slick(options);
I've been googling this issue and it seems other people have similar issues but I couldn't find a solution.
Any ideas appreciated!
Yeah it does seem that slick will only allow adaptiveHeight on single sliding carousels.
In the docs on adaptiveHeight it says this...
Enables adaptive height for single slide horizontal carousels.
It's funny I never expected this behaviour from slick, I assumed adaptive height worked in all cases. But apparently not.
This is a little bit hacky but might cover a solution for your website to enable adaptive height on multi slide sliders. This essentially finds the tallest slides currently on display and adds a height to the .slick-list. Using css transition on this element gives the slick adaptiveHeight effect.
Also we have a .on('resize') event which re-runs the slider height checks incase the slide content is fluid and the slide heights change responsively.
Read my comments in script to see what is going on...
Also see fiddle here... https://jsfiddle.net/joshmoto/1a5vwr3j/
// my slick slider options
var options = {
slidesToShow: 2,
slidesToScroll: 2,
dots: true,
arrows: false,
dotsClass: 'slick-dots slick-dots-black',
adaptiveHeight: true,
};
// my slick slider as constant object
const mySlider = $('.slider').on('init', function(slick) {
// on init run our multi slide adaptive height function
multiSlideAdaptiveHeight(this);
}).on('beforeChange', function(slick, currentSlide, nextSlide) {
// on beforeChange run our multi slide adaptive height function
multiSlideAdaptiveHeight(this);
}).slick(options);
// our multi slide adaptive height function passing slider object
function multiSlideAdaptiveHeight(slider) {
// set our vars
let activeSlides = [];
let tallestSlide = 0;
// very short delay in order for us get the correct active slides
setTimeout(function() {
// loop through each active slide for our current slider
$('.slick-track .slick-active', slider).each(function(item) {
// add current active slide height to our active slides array
activeSlides[item] = $(this).outerHeight();
});
// for each of the active slides heights
activeSlides.forEach(function(item) {
// if current active slide height is greater than tallest slide height
if (item > tallestSlide) {
// override tallest slide height to current active slide height
tallestSlide = item;
}
});
// set the current slider slick list height to current active tallest slide height
$('.slick-list', slider).height(tallestSlide);
}, 10);
}
// when window is resized
$(window).on('resize', function() {
// run our multi slide adaptive height function incase current slider active slides change height responsively
multiSlideAdaptiveHeight(mySlider);
});
body {
background: skyblue;
margin: 0;
padding: 20px;
}
.slick-list {
transition: all .5s ease;
}
.aslide {
background: yellow;
}
<div class="slider">
<div class="aslide">1</div>
<div class="aslide">2<br/>2<br/>2</div>
<div class="aslide">3<br/>3<br/>3<br/>3<br/>3</div>
<div class="aslide">4<br/>4<br/>4</div>
<div class="aslide">5</div>
<div class="aslide">6<br/>6<br/>6</div>
<div class="aslide">7<br/>7<br/>7<br/>7<br/>7</div>
<div class="aslide">8<br/>8</div>
<div class="aslide">9<br/>9<br/>9<br/>9<br/>9<br/>9</div>
<div class="aslide">10<br/>10<br/>10</div>
<div class="aslide">11</div>
<div class="aslide">12<br/>12</div>
</div>
<link href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick-theme.min.css" rel="stylesheet" />
<link href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick.min.js"></script>

How to avoid accidental click events while dragging?

I have a slider built using Slick, each slide has a data attribute that get copied to an input field when a slide get clicked then the form with the value on that input field get submited.
The problem is that if i have a a multiple slides "maybe by choosing Kissen=>Sitz from the select boxes above then try to drag the slides to scroll through them that may cause a click event (that happens most of the time but not always) so im wondering if there is an easy way to prevent that accidental clicks?
<form name="product_select" id="product_select_form" action="conctact-details/" method="post">
<input type="text" id="product_id" name="product_id">
</form>
<div class="slick-slider">
<div class="slick-slide" data-product-id="1" data-product-cat="1"><img src="https://www.solodev.com/assets/carousel/image1.png">Orthopädisches Sitzkissen</div>
<div class="slick-slide" data-product-id="2" data-product-cat="1"><img src="https://www.solodev.com/assets/carousel/image2.png">Hämorrhoiden Kissen</div>
<div class="slick-slide" data-product-id="3" data-product-cat="1"><img src="https://www.solodev.com/assets/carousel/image3.png">Rückenkissen</div>
<div class="slick-slide" data-product-id="4" data-product-cat="1"><img src="https://www.solodev.com/assets/carousel/image4.png">Comfort Cushion</div>
<div class="slick-slide" data-product-id="5" data-product-cat="1"><img src="https://www.solodev.com/assets/carousel/image5.png">All-in-one</div>
<div class="slick-slide" data-product-id="6" data-product-cat="1"><img src="https://www.solodev.com/assets/carousel/image6.png">Aufstehkissen</div>
<div class="slick-slide" data-product-id="7" data-product-cat="1"><img src="https://www.solodev.com/assets/carousel/image7.png">Wedge Cushion</div>
</div>
$(document).ready(function() {
$('.slick-slider').hide();
$('.slick-slider').slick({
dots: true,
infinite: false,
speed: 300,
slidesToShow: 4,
slidesToScroll: 4,
responsive: [{
breakpoint: 1024,
settings: {
slidesToShow: 3,
slidesToScroll: 3
}
},
{
breakpoint: 800,
settings: {
slidesToShow: 2,
slidesToScroll: 2
}
},
{
breakpoint: 500,
settings: {
slidesToShow: 1,
slidesToScroll: 1
}
}
]
});
});
$(".slick-slide").click(function() {
$product_id = $(this).data('product-id');
$('#product_id').val($product_id);
$('#product_select_form').submit();
https://jsfiddle.net/arabtornado/gjxnmk4p/198/
$('.slick-slide').on('mousedown', function (evt) {
$('.slick-slide').on('mouseup mousemove', function handler(evt) {
if (evt.type === 'mouseup') {
$product_id = $(this).data('product-id');
$('#product_select_form').submit();
$('#product_id').val($product_id);
}
$('.slick-slide').off('mouseup mousemove', handler);
});
});
Refrance:
How to distinguish mouse "click" and "drag"
I also had trouble with this.
What I did was to track if there are movement between the mousedown event and the mouseup event. I count every movement of the mouse and just add it to a counter.
Every mousedown, I reset the counter to 0.
If the movement is too large, then it is not considered a click.
let dragmovement = 0;
$('#slick-selector').click(function(e){
if(dragmovement <= 20){
// proceed with click event if mouse movement is minimal
// change constant depending on your level of tolerance
console.log("clicked, not dragged")
}
})
$(".#slick-selector").mousedown(function(e){dragmovement = 0;
//onmousedown inside the element, set counter to 0
// start tracking mouse movement
$(document).mousemove(function(){dragmovement++;})
//even mouse movement outside the slick is tracked
//every movement will add +1 to counter
}).mouseup(function(){
$(document).unbind('mousemove')
// release mouse movement tracker
})
`

"bxslider jquery" change the slide mode at specified width

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>

jQuery not displaying correctly fixed on refresh

I have a thumbnail slider on my web page which i am developing. Now when i go into the website it shows only a little block of the picture but once i refresh the page all is good, any ideas why this happens
http://www.ap2x.gbes.co.za/1/1.html
that is the page in question
i have tested on firefox, chrome and IE. Error does not seem to be browser specific
Slider works perfectly fine off line with no such problem.
I have no idea what could be causing this
$(function() {
// wrap all thumbs in a <div> for the 3x3 grid
$div = null;
$('#thumbs').children().each(function(i) {
if ( i % 9 == 0) {
$div = $( '<div />' );
$div.appendTo( '#thumbs' );
}
$(this).appendTo( $div );
$(this).addClass( 'itm'+i );
$(this).click(function() {
$('#images').trigger( 'slideTo', [i, 0, true] );
});
});
$('#thumbs img.itm0').addClass( 'selected' );
// the big-image carousel
$('#images').carouFredSel({
direction: 'up',
circular: false,
infinite: false,
width: 500,
height: 281,
items: 1,
auto: false,
scroll: {
fx: 'directscroll',
onBefore: function() {
var pos = $(this).triggerHandler( 'currentPosition' );
$('#thumbs img').removeClass( 'selected' );
$('#thumbs img.itm'+pos).addClass( 'selected' );
var page = Math.floor( pos / 9 );
$('#thumbs').trigger( 'slideToPage', page );
}
}
});
// the thumbnail-carousel
$('#thumbs').carouFredSel({
direction: 'up',
circular: false,
infinite: false,
width: 550,
height: 150,
items: 1,
align: false,
auto: false,
});
});
It sounds like it doesn't work until the images have been loaded so you either need to tell the slider how big the images will be once they are loaded or wait till they are loaded before running your script.
Does adding the following CSS solve the problem?
#images img {
height: 281px;
width: 500px;
}
I can't get the bug again to test it myself.
I bet you're viewing this website with Chrome.
There is a nasty bug with this browser when he cannot determine the height of an element.
A workaround would be setting width and height to each slider image manually through css.

Categories