how to change dynamical attribute on slider - javascript

I have a dynamical slider. And trying to add tabindex="-1" attribute to child when it's parent li element has aria-hidden="true" attribute.
Here is Fiddle example :
Or see below snippet :
$('.bxslider').bxSlider({
minSlides: 3,
maxSlides: 3,
moveSlides: 1,
slideWidth: 150,
slideMargin: 0
});
$('li[aria-hidden=true]').children().attr('tabindex', '-1');
body {
margin: 50px 0 0 30px;
}
.my-slider {
text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bxslider/4.2.12/jquery.bxslider.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/bxslider/4.2.12/jquery.bxslider.min.css" rel="stylesheet" />
<ul class="my-slider bxslider">
<li>aaa </li>
<li>bbb </li>
<li>ccc </li>
<li>dd </li>
<li>eee </li>
</ul>
How do I change the code as dynamical attribute ?
Please help

As Louys reported you should use onSlideAfter calback function :
but some small addition in order to remove tabindex you should remove from all li's children that add it to li with aria-hidden=true
by adding $('.bxslider li').children().removeAttr('tabindex');
See below Snippet :
$('.bxslider').bxSlider({
minSlides: 3,
maxSlides: 3,
moveSlides: 1,
slideWidth: 150,
slideMargin: 0,
onSlideAfter : function(elt,oldIndex,neIndex) {
$('.bxslider li').children().removeAttr('tabindex');
$('li[aria-hidden=true]').children().attr('tabindex', '-1');
}
});
$('li[aria-hidden=true]').children().attr('tabindex', '-1');
body {
margin: 50px 0 0 30px;
}
.my-slider {
text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bxslider/4.2.12/jquery.bxslider.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/bxslider/4.2.12/jquery.bxslider.min.css" rel="stylesheet" />
<ul class="my-slider bxslider">
<li>aaa </li>
<li>bbb </li>
<li>ccc </li>
<li>dd </li>
<li>eee </li>
</ul>

You have to use the BxSlider onSlideAfter callback.
Executes immediately after each slide transition. Function argument is the current slide element (when transition completes).
See documentation.
$('.bxslider').bxSlider({
minSlides: 3,
maxSlides: 3,
moveSlides: 1,
slideWidth: 150,
slideMargin: 0,
onSlideAfter: function(){
$('li[aria-hidden=true]').children().attr('tabindex', '-1');
}
});
Your Fiddle Updated.

Related

Slick slider not working when initialSlide is set

I can't figure out why the slides do not slide when I have an initialSlide set. I'm referring to the docs at https://kenwheeler.github.io/slick/, but couldn't figure out what the problem is.
$('.container').slick({
initialSlide: 4,
infinite: false,
slidesToShow: 3,
slidesToScroll: 1
})
* {
box-sizing: border-box;
}
.container {
width: 120px;
}
.slide {
border: 1px solid red;
width: 40px;
}
<link href="https://cdn.jsdelivr.net/npm/slick-carousel#1.8.1/slick/slick.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/slick-carousel#1.8.1/slick/slick.min.js"></script>
<div class="container">
<div class="slide">1</div>
<div class="slide">2</div>
<div class="slide">3</div>
<div class="slide">4</div>
<div class="slide">5</div>
</div>
You have set the initial slide to 4 (i.e. index 4 is slide #5) - this is the last slide in your carousel. The problem is that your carousel is showing 3 slides, so you want the initial slide to be #3 which has index: 2:
(total slides - slidesToShow) = 5-3 = 2
If you set initialSlide: 2 this will still show the last 3 slides but it also sets up the "previous" button to go to slide #2 which will trigger a scroll. (The Next button won't have any effect of course, because you are showing the last slide and have infinite:false)
Working Example:
$('.container').slick({
initialSlide: 2,
infinite: false,
slidesToShow: 3,
slidesToScroll: 1
})
* {
box-sizing: border-box;
}
.container {
width: 120px;
}
.slide {
border: 1px solid red;
width: 40px;
}
<link href="https://cdn.jsdelivr.net/npm/slick-carousel#1.8.1/slick/slick.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/slick-carousel#1.8.1/slick/slick.min.js"></script>
<div class="container">
<div class="slide">1</div>
<div class="slide">2</div>
<div class="slide">3</div>
<div class="slide">4</div>
<div class="slide">5</div>
</div>
it is to work
$('.container').slick({
infinite: false,
slidesToShow: 2,
slidesToScroll: 1,
initialSlide: 3
})
you have 5 slides, but the initial one you specified is 4, and at the same time show 3. but the initial 1 is slide 2, the Initial 4 is slide 5, but slidesToShow: 3. the slider doesn't have any spare slides to show
while I was writing the answer it is already given in the comments
Since 2014 initialSlide not working in responsive config, so can use
$('.selector').slick('slickGoTo', 5);

slick-slider with Corresponding Image Section

I've made a simple slider using Ken Wheeler's slick-slider (https://kenwheeler.github.io/slick/), and I've added an image display function that switches another image below the slider (not the actual slider image) to correspond with the slider. I'd like this for a product carousel that will have a banner image that corresponds with the product in the slick-slider. The below code is functional, but was wondering if there's a cleaner way achieve this. I got hung-up and perhaps long-winded when checking for the inactive slides, and hiding the corresponding images. Thanks.
$(document).ready(function () {
$('.my-slide-wrapper').slick({
dots: true,
infinite: true,
speed: 1,
slidesToShow: 1,
slidesToScroll: 1
});
$("button.slick-arrow").click(function () {
if ($("#slick-slide00").hasClass("slick-active") && (!$("#slick-slide01 #slick-slide02").hasClass("slick-active"))) {
$("#myImage00").addClass("im-showing"),
$("#myImage01").removeClass("im-showing"),
$("#myImage02").removeClass("im-showing");
}
else if ($("#slick-slide01").hasClass("slick-active") && (!$("#slick-slide02 #slick-slide00").hasClass("slick-active"))) {
$("#myImage01").addClass("im-showing"),
$("#myImage02").removeClass("im-showing"),
$("#myImage00").removeClass("im-showing");
}
else {
$("#myImage02").addClass("im-showing"),
$("#myImage01").removeClass("im-showing"),
$("#myImage00").removeClass("im-showing");
}
});
});
Working version on CodePen: https://codepen.io/jakeos/pen/povXPyd
You should check out "Slider Syncing" in the documentation. It does exactly that. In your case, you need to setup both as sliders and use your top slider as the navigation for the bottom one.
I changed your HTML a bit to make it easier to understand
Here's a working fiddle.
HTML
<!-- This is just a slider using Ken Wheeler's slick-slider (https://kenwheeler.github.io/slick/), and I've added an image display function that switches the image below (the slider) to correspond with the slider. It will ultimately be for a product carousel that will have a banner image that corresponds with the product in the slider. -->
<body>
<div class="my-slide-container">
<div id="top-slider" class="my-slide-wrapper">
<img class="slide slide00" src="https://dummyimage.com/300x180/ff0000/ffffff.jpg&text=Slide+1">
<img class="slide slide01" src="https://dummyimage.com/300x180/00ff00/000000.jpg&text=Slide+2">
<img class="slide slide02" src="https://dummyimage.com/300x180/0000ff/ffffff.jpg&text=Slide+3">
</div>
<div id="bottom-slider" class="my-slide-wrapper">
<img class="slide slide00" src="https://dummyimage.com/300x180/ff0000/ffffff.jpg&text=Image+1">
<img class="slide slide01" src="https://dummyimage.com/300x180/00ff00/000000.jpg&text=Image+2">
<img class="slide slide02" src="https://dummyimage.com/300x180/0000ff/ffffff.jpg&text=Image+3">
</div>
</div>
</body>
CSS
.my-slide-container {
margin: 30px;
}
.my-slide-wrapper,
.my-image-wrapper {
margin: 0 auto;
max-width: 300px;
}
img {
max-width: 300px;
width: 100%;
}
.slick-dots li {
margin: 0;
}
.slick-next::before,
.slick-prev::before {
color: #000;
opacity: 1;
}
.my-image {
visibility: hidden;
position: absolute;
}
#myImage00 {
visibility: visible;
}
.im-hiding {
visibility: hidden;
}
.im-showing {
visibility: visible;
}
JS
$(document).ready(function () {
$('#top-slider').slick({
asNavFor: '#bottom-slider',
dots: true,
infinite: true,
speed: 1,
slidesToShow: 1,
slidesToScroll: 1
});
$('#bottom-slider').slick({
arrows: false,
dots: false,
draggable: false,
infinite: true,
speed: 1,
slidesToShow: 1,
slidesToScroll: 1
});
});

Slick Carousel - Disable controls and interactions by external order

I'm learning JavaScript and I've got a simple problem that I don't know how to deal with it.
What I want to achieve is to 'hold' or 'freeze' a slide disabling all kind of possible navigation (keyboard arrows, click and drag, touch interaction) by only clicking a button when the user desires. By clicking this button the user enables or disables the navigation controls with the slider.
So, once clicked this button the user can't navigate on the slides. The user has to click again on the button to enable the controls.
This is what I got so far:
jQuery(document).ready(function($) {
$('.slider').slick({
infinite: true,
fade: false,
centerMode: true,
variableWidth: true,
slidesToShow: 3,
slidesToScroll: 1,
arrows: false,
autoplay: false
});
});
var hold = false;
$('#hold').click(function() {
$(this).attr("class", "active disabled");
if (hold == false) {
$('.slider').slick({
accesibility: false,
draggable: false,
swipe: false,
touchMove: false
});
hold = true;
} else {
$('.slider').slick({
accesibility: true,
draggable: true,
swipe: true,
touchMove: true
});
hold = false;
$("#hold").attr("class", "disabled");
}
});
.card {
margin: 10px;
padding: 50px 100px;
background-color: silver;
color: white;
}
.active {
color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src='//cdn.jsdelivr.net/jquery.slick/1.5.7/slick.min.js' type='text/javascript'></script>
<link rel="stylesheet" type="text/css" href="//cdn.jsdelivr.net/jquery.slick/1.5.9/slick.css" />
<div class="slider">
<h1 class="card">1</h1>
<h1 class="card">2</h1>
<h1 class="card">3</h1>
<h1 class="card">4</h1>
<h1 class="card">5</h1>
</div>
<button id="hold" class="disabled">HOLD</button>
What could I've been missing?
Your help is really appreciated!
Use slickSetOption to set an individual value live. See the Methods section at http://kenwheeler.github.io/slick/
Below is a working example.
var slider = $("#slider");
slider.slick({
arrows: false,
centerMode: true,
infinite: true,
slidesToShow: 3,
slidesToScroll: 1,
variableWidth: true
});
var hold = false;
$("#hold").click(function() {
slider.slick("slickSetOption", "accessibility", hold);
slider.slick("slickSetOption", "draggable", hold);
slider.slick("slickSetOption", "swipe", hold);
slider.slick("slickSetOption", "touchMove", hold);
hold = !hold;
$(this).toggleClass("disabled");
});
h1 {
background-color: silver;
color: white;
margin: 10px;
padding: 50px 100px;
}
.disabled {
color: red;
}
<link href="https://cdn.jsdelivr.net/jquery.slick/1.6.0/slick.css" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/jquery.slick/1.6.0/slick.min.js"></script>
<div id="slider">
<h1>1</h1>
<h1>2</h1>
<h1>3</h1>
<h1>4</h1>
<h1>5</h1>
</div>
<button id="hold">HOLD</button>

bxSlider last slide empty

I have bxSlider integrated in an existing application showing three different slides.
Each slide contains a HTML canvas which is periodically updated with a new JCharts graph.
It works perfect! Only... the last slide does appear, but does not show the content of the canvas.
The following bxSlider element is used. In this case the canvas with id loadedClassesLineChart is showm, but does not show the graph. When i change the order of the tags the content of the last canvas is not shown (although the canvas is shown an a pager is shown with 3 dots)
<ul class="bxslider" id="rdstats">
<li><p style="background-color:rgb(231, 239, 252);margin-top: -4px;font-weight: bold;padding:6px 6px 6px 6px;">Average CPU Load/CPUs</p><br/>
<canvas id="cpuLoadRadarChart" width="200" height="200" style="margin: 0px 0px 0px 0px;"></canvas>
</li>
<li><p style="background-color:rgb(231, 239, 252);margin-top: -4px;font-weight: bold;padding:6px 6px 6px 6px;">Heapsize allocation</p><br/>
<canvas id="heapSizeStackedBarChart" width="200" height="200" style="margin: 0px 0px 0px 0px;"></canvas>
</li>
<li><p style="background-color:rgb(231, 239, 252);margin-top: -4px;font-weight: bold;padding:6px 6px 6px 6px;">Loaded classes</p><br/>
<canvas id="loadedClassesLineChart" width="200" height="200" style="margin: 0px 0px 0px 0px;"></canvas>
</li>
</ul>
When adding an extra empty <li> </li> after the last </li> all three graphs are shown and the fourth empty slide is shown.
bxSlider is started using the document ready function.
$(document).ready(function() {
$('#rdstats').each(function() {
var _this = $(this).bxSlider({
controls: false,
auto: true,
autoHover: true,
minSlides: 1,
maxSlides: 1,
adaptiveHeight: true,
slidewidth: 200,
slideMargin: 2});
_this.mouseenter(function() {
_this.stopAuto();
}).mouseleave(function() {
_this.startAuto();
});
});
What i have tried;
UseCSS : false
slideWidth : 200
minSlides : different values
maxSlides : different values
adaptiveHeight: false
reproducable on FireFox, Safari and Opera
Anyone able to help me out on this one ?
The problem was, the plugin bxslider clones some of the elements(<li></li>) which has canvas as child. So the canvas inside newly cloned element is NOT initialized using ChartJS
I have modified the code a little bit to support this.
// Refreshes bxslider with id "rdstats" with new data.
function refreshcpuLoadRadarChart() {
// Replace the chart canvas element
$('.cpuLoadRadarChart').replaceWith('<canvas class="cpuLoadRadarChart" width="200" height="200" style="margin: 0px 0px 0px 0px;"></canvas>');
// Get the context of the canvas element we want to select
var ctx = $('.cpuLoadRadarChart').get(0).getContext("2d");
new Chart(ctx).Radar({"labels":["10:54","10:55","10:56","10:57","10:58","10:59","11:00","11:01","11:02","11:03","11:04","11:05","11:06","11:07","11:08","11:09"],"datasets":[{"label":"myserver","fillColor":"rgba(165,222,11,0.2)","strokeColor":"rgba(165,222,11,1)","pointColor":"rgba(165,222,11,1)","pointStrokeColor":"#fff","pointHighlightFill":"#fff","pointHighlightStroke":"rgba(165,222,11,1)","data":[0.03,0.01,0.2,0.53,0.34,0.2,0.43,0.28,0.17,0.28,0.24,0.32,0.2,0.45,0.42,0.15]}]}, {
responsive: true,
animation: false,
tooltipFontSize: 10,
tooltipTitleFontSize: 10,
tooltipXOffset: 5,
scaleOverride: true,
scaleShowLabels: true,
scaleSteps: 6,
scaleStepWidth: 0.5,
scaleStartValue: 0,
scaleFontSize: 10
});
setTimeout(function () {
refreshcpuLoadRadarChart();
}, 30000);
}
// Refreshes bxslider with id "rdstats" with new data.
function refreshHeapUsageBarChart() {
$('.heapSizeStackedBarChart').replaceWith('<canvas class="heapSizeStackedBarChart" width="200" height="200" style="margin: 0px 0px 0px 0px;"></canvas>');
$('.heapSizeStackedBarChart').each(function(pos,value){
var ctx = $(value).get(0).getContext("2d");
new Chart(ctx).StackedBar({"labels":["myserver","myserver2","myserver3"],"datasets":[{"label":"Free %","fillColor":"rgba(255,255,255,0.7)","strokeColor":"rgba(255,255,255,1)","pointColor":"rgba(255,255,255,1)","pointStrokeColor":"rgba(255,255,255,1)","pointHighlightFill":"rgba(255,255,255,1)","pointHighlightStroke":"rgba(255,255,255,1)","data":[50,50,50]},{"label":"Tenured Comm not Used%","fillColor":"rgba(165,222,11,0.7)","strokeColor":"rgba(165,222,11,1)","pointColor":"rgba(165,222,11,1)","pointStrokeColor":"rgba(165,222,11,1)","pointHighlightFill":"rgba(165,222,11,1)","pointHighlightStroke":"rgba(165,222,11,1)","data":[14,14,14]},{"label":"Tenured Used%","fillColor":"rgba(199,193,1,0.7)","strokeColor":"rgba(199,193,1,1)","pointColor":"rgba(199,193,1,1)","pointStrokeColor":"rgba(199,193,1,1)","pointHighlightFill":"rgba(199,193,1,1)","pointHighlightStroke":"rgba(199,193,1,1)","data":[21,21,21]},{"label":"Survivor Comm not Used%","fillColor":"rgba(227,158,3,0.7)","strokeColor":"rgba(227,158,3,1)","pointColor":"rgba(227,158,3,1)","pointStrokeColor":"rgba(227,158,3,1)","pointHighlightFill":"rgba(227,158,3,1)","pointHighlightStroke":"rgba(227,158,3,1)","data":[1,1,1]},{"label":"Survivor Used%","fillColor":"rgba(246,120,15,0.7)","strokeColor":"rgba(246,120,15,1)","pointColor":"rgba(246,120,15,1)","pointStrokeColor":"rgba(246,120,15,1)","pointHighlightFill":"rgba(246,120,15,1)","pointHighlightStroke":"rgba(246,120,15,1)","data":[0,0,0]},{"label":"Eden Comm not Used%","fillColor":"rgba(254,83,38,0.7)","strokeColor":"rgba(254,83,38,1)","pointColor":"rgba(254,83,38,1)","pointStrokeColor":"rgba(254,83,38,1)","pointHighlightFill":"rgba(254,83,38,1)","pointHighlightStroke":"rgba(254,83,38,1)","data":[11,11,11]},{"label":"Eden Used%","fillColor":"rgba(251,50,68,0.7)","strokeColor":"rgba(251,50,68,1)","pointColor":"rgba(251,50,68,1)","pointStrokeColor":"rgba(251,50,68,1)","pointHighlightFill":"rgba(251,50,68,1)","pointHighlightStroke":"rgba(251,50,68,1)","data":[3,3,3]}]}, {
responsive: true,
animation: false,
scaleSteps: 10,
scaleStepWidth: 10,
scaleStartValue: 0,
scaleOverride: true,
tooltipXOffset: -25,
tooltipFontSize: 10,
tooltipTitleFontSize: 10
});
})
setTimeout(function () {
refreshHeapUsageBarChart();
}, 30000);
}
// Refreshes bxslider with id "rdstats" with new data.
function refreshLoadedClassesLineChart() {
// Replace the chart canvas element
$('.loadedClassesLineChart').replaceWith('<canvas class="loadedClassesLineChart" width="200" height="200" style="margin: 0px 0px 0px 0px;"></canvas>');
var ctx = $('.loadedClassesLineChart').get(0).getContext("2d");
new Chart(ctx).Line({"labels":["10:55","10:56","10:57","10:58","10:59","11:00","11:01","11:02","11:03","11:04","11:05","11:06","11:07","11:08","11:09","11:10"],"datasets":[{"label":"myserver","fillColor":"rgba(165,222,11,0.2)","strokeColor":"rgba(165,222,11,1)","pointColor":"rgba(165,222,11,1)","pointStrokeColor":"#fff","pointHighlightFill":"#fff","pointHighlightStroke":"rgba(165,222,11,1)","data":[15617,15617,15617,15617,15617,15617,15617,15617,15617,15617,15617,15617,15617,15617,15617,15617]}]}, {
responsive: true,
animation: false,
tooltipFontSize: 10,
tooltipTitleFontSize: 10,
tooltipXOffset: 5,
scaleShowLabels: true,
scaleFontSize: 10
});
setTimeout(function () {
refreshLoadedClassesLineChart();
}, 30000);
}
$(document).ready(function () {
console.log('document ready');
$('.bxslider').bxSlider({
controls: false,
auto: true,
autoHover: true,
minSlides: 1,
maxSlides: 1,
adaptiveHeight: true,
slidewidth: 200,
slideMargin: 2,
onSliderLoad: function(){
refreshcpuLoadRadarChart();
refreshHeapUsageBarChart();
refreshLoadedClassesLineChart();
}
});
});
Checkout this fiddle
or simply set onSlideAfter reload where 3000 mean time how long to wait till reload from start (infinitiLoop must be false):
infiniteLoop: false,
onSlideAfter: function(){
setTimeout(function(){_this.reloadSlider()},3000);
}

JQuery Cycle not working right

I am trying to do a function after my first slide has shown. I basically want to do the same function after each slide, but my 2nd slide is just still. Nothing is fading in or coming in.
Here is my JQuery
$("#slideshow").cycle({
fx: 'scrollHorz',
pager: '#slideshow-nav',
speed: 600,
timeout: 7000,
pauseOnPagerHover: true,
containerResize: false,
slideResize: false,
fit: 1,
before: beforeSlide,
after: afterSlide
});
function beforeSlide() {
$("#slideText").css('padding-left', '0px');
$("#slideText").css('opacity', '0');
}
function afterSlide() {
$("#slideText").animate({ opacity: 1, paddingLeft: '+=100px'}, 600);
}
Here is my html
<div id="slideshow" class="slides">
<div class="slide" style="background-image: url('slideOne.jpg'); background-color: #e3d7bd;">
<div id="slideText">
<h1>asdf</h1>
<br />
<p>asdf</p>
<p>asdf</p><br />
Get started today
</div>
</div>
<div class="slide" style="background-color: #fff;">
<img class="slideTwoImage" src="slideTwoKid.png"></img>
<div id="slideText">
<h1>Test.</h1>
<br />
<p>asdf</p>
<p>asdf</p><br />
Get started today
</div>
</div>
<!-- <div class="slide" style="background-image: url('slideTwo.jpg'); background-color: #fff; display: none;"></div>
<div class="slide" style="background-image: url('slideThree.jpg'); background-color: #000; display: none;"></div> -->
</div>
It works for the first slide..the animation for the text, but on the 2nd slide it is not working.
Change containerResize: false to containerResize: true then it should work.
See demo here
I figured it out. You have to name elements in the before and after function differently.
I had them both named #slideText as you can tell in the functions. Just name them separate.
$("#slideshow").cycle({
fx: 'scrollHorz',
pager: '#slideshow-nav',
speed: 600,
timeout: 7000,
pauseOnPagerHover: true,
containerResize: true,
slideResize: false,
fit: 1,
before: beforeSlide,
after: afterSlide
});
function beforeSlide() {
$("#slideText").css('padding-left', '0px');
$("#slideText").css('opacity', '0');
$("#slideTextTwo").css('padding-left', '0px');
$("#slideTextTwo").css('opacity', '0');
}
function afterSlide() {
$("#slideText").animate({ opacity: 1, paddingLeft: '+=100px'}, 600);
$("#slideTextTwo").animate({ opacity: 1, paddingLeft: '+=100px'}, 600);
}
So now I can make changes on separate slides the way I intended.

Categories