The Swiper Slider doesn't update the slide active state while playing the slider - javascript

For some reason, I have to use Swiper Slider V4.5.3. I set up a carousel and the content slider, but when clicking the carousel slide item, it should change the active state of the current item, but it doesn't. The active state is always stopped at the first item.
I tried many ways to fix it, but no luck. Even add slideChange event to output the activeIndex value, it always shows 0.
Hope anyone can give me the right direction. Thanks!
var Nav = new Swiper('#nav', {
spaceBetween: 0,
slidesPerView: 4,
watchSlidesVisibility: true,
watchSlidesProgress: true
});
var NavContent = new Swiper('#content', {
spaceBetween: 20,
thumbs: {
swiper: Nav
}
});
.swiper-slide-active {
color: #f00;
}
.swiper-slide {
cursor: pointer;
}
#content {
margin-top: 2em;
}
<script src="https://nybilu.com/sources/swiper.min.js"></script>
<link href="https://nybilu.com/sources/swiper.min.css" rel="stylesheet" />
<div id="nav" class="swiper-container">
<div class="swiper-wrapper">
<div class="swiper-slide">Nav 1</div>
<div class="swiper-slide">Nav 2</div>
<div class="swiper-slide">Nav 3</div>
<div class="swiper-slide">Nav 4</div>
<div class="swiper-slide">Nav 5</div>
</div>
</div>
<div id="content" class="swiper-container">
<div class="swiper-wrapper">
<div class="swiper-slide">Content 1</div>
<div class="swiper-slide">content 2</div>
<div class="swiper-slide">content 3</div>
<div class="swiper-slide">content 4</div>
<div class="swiper-slide">content 5</div>
</div>
</div>

Related

jQuery: alternate switching of classes in several div blocks

I have 2 identical div blocks on the page, inside of which there are several div blocks with different texts. It looks something like this:
<div class="dynamic_titles">
<div class="dynamic_title active">text 1</div>
<div class="dynamic_title inactive">text 2</div>
<div class="dynamic_title inactive">text 3</div>
<div class="dynamic_title inactive">text 4</div>
<div class="dynamic_title inactive">text 5</div>
</div>
<div class="dynamic_titles">
<div class="dynamic_title active">text 6</div>
<div class="dynamic_title inactive">text 7</div>
<div class="dynamic_title inactive">text 8</div>
<div class="dynamic_title inactive">text 9</div>
<div class="dynamic_title inactive">text 10</div>
</div>
I need to change classes from inactive to active in each dynamic_title block in turn. That is, the next one takes active, and the previous one with active in inactive and so on in a circle.
When I have one dynamic_titles block, everything works fine, but 2 interfere with each other, break. I'm trying not to make 2 functions for each block separately, I want to make one universal one that would be applied to each block separately.
Now I have such a code, but it does not work as expected. It runs once and goes no further. If done without .each, it works, but again not as expected and eventually breaks. What is my mistake?
$('.dynamic_titles').each(function () {
var index = 1,
max = $(this).find('.dynamic_title').length;
function setActiveHeadline() {
setTimeout(function () {
$(this).find('.active').removeClass('active').addClass('inactive');
index++;
if (index > max) {
index = 1;
}
$(this).find('.dynamic_title:nth-of-type(' + index + ')').addClass('active').removeClass('inactive');
setActiveHeadline();
}, 3000);
}
setActiveHeadline();
widthTitle = $(this).find('.dynamic_title.active').width();
$(this).css({
'width': widthTitle,
});
function setWidthHeadlines() {
setTimeout(function () {
widthTitle = $(this).find('.dynamic_title.active').width();
$(this).css({
'width': widthTitle,
});
setWidthHeadlines();
}, 3000);
}
setWidthHeadlines();
})
Thank you for your help!
I think you could simplify this into one function that uses setInterval, please see the following snippet:
$(function(){
//use setInterval to continue the changes
setInterval(() => {
//iterate the blocks
$('div.dynamic_titles').each(function() {
//get the children
const $children = $(this).find('div.dynamic_title');
//get the number of children
const numofchildren = $children.length;
//index for switching active in children
let activeindex = 0;
//iterate children to find the active one
$children.each(function(i, el) {
//if active, remove active and add inactive classNames
//store the index
//break the each loop
if($(el).hasClass('active')){
$(el).removeClass('active').addClass('inactive');
activeindex = i + 1;
return false;
}
});
//if index has reached the last child, reset to zero
if(activeindex > numofchildren - 1){
activeindex = 0;
}
//set the next child to active and remove inactive className
$children[activeindex].classList.add('active');
$children[activeindex].classList.remove('inactive');
});
}, 3000);
})
.active {
color:green;
}
.inactive {
color:grey;
}
<div class="dynamic_titles">
<div class="dynamic_title active">text 1</div>
<div class="dynamic_title inactive">text 2</div>
<div class="dynamic_title inactive">text 3</div>
<div class="dynamic_title inactive">text 4</div>
<div class="dynamic_title inactive">text 5</div>
</div>
<div class="dynamic_titles">
<div class="dynamic_title active">text 6</div>
<div class="dynamic_title inactive">text 7</div>
<div class="dynamic_title inactive">text 8</div>
<div class="dynamic_title inactive">text 9</div>
<div class="dynamic_title inactive">text 10</div>
</div>
<script
src="https://code.jquery.com/jquery-3.6.1.js"
integrity="sha256-3zlB5s2uwoUzrXK3BT7AX3FyvojsraNFxCc2vC/7pNI="
crossorigin="anonymous"></script>

JavaScript Sortable do function on list changes?

How can I make a function fire when a sortable list changes?
I have looked for some examples but they are making the lists different to how I am and I cant see how to do it with how my sortable lists are generated. Perhaps I am using a different Sortable version or something?
This is how I make my lists...
<script>
Sortable.create(plansList, {
animation: 100,
group: 'list-1',
draggable: '.recipe',
handle: '.handle',
sort: true,
filter: '.sortable-disabled',
chosenClass: 'active'
});
Sortable.create(suggestionsList, {
animation: 100,
group: 'list-1',
draggable: '.recipe',
handle: '.handle',
sort: true,
filter: '.sortable-disabled',
chosenClass: 'active'
});
</script>
As you can see I have 2 lists. I want both to fire the same function when they change, but if both lists change (because an item was moved from one list to the other) I don't want the function to fire twice.
Can anyone help?
Thanks,
Chris
Event onEnd will only fire once, as requested. But it will fire if also no change has been made. So you might need to compare old index to new index.
var example2Left = document.querySelector("#example2-left");
var example2Right = document.querySelector("#example2-right");
new Sortable(example2Left, {
group: 'shared', // set both lists to same group
animation: 150,
onEnd: foo
});
new Sortable(example2Right, {
group: 'shared',
animation: 150,
onEnd: foo
});
function foo(ev) {
var to = ev.to;
var from = ev.from;
var oldIndex = ev.oldIndex;
var newIndex = ev.newIndex;
if (to != from || oldIndex != newIndex) {
singleOnChange(ev)
}
}
function singleOnChange(ev) {
console.log("list(s) changed")
}
.col {
width: 50%;
float: left;
}
.list-group-item {
padding: 10px;
margin: 2px;
background: blue;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Sortable/1.15.0/Sortable.min.js" integrity="sha512-Eezs+g9Lq4TCCq0wae01s9PuNWzHYoCMkE97e2qdkYthpI0pzC3UGB03lgEHn2XM85hDOUF6qgqqszs+iXU4UA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<div id="example2-left" class="list-group col">
<div class="list-group-item">Item 1</div>
<div class="list-group-item">Item 2</div>
<div class="list-group-item">Item 3</div>
<div class="list-group-item">Item 4</div>
<div class="list-group-item">Item 5</div>
<div class="list-group-item">Item 6</div>
</div>
<div id="example2-right" class="list-group col">
<div class="list-group-item">Item 1</div>
<div class="list-group-item">Item 2</div>
<div class="list-group-item">Item 3</div>
<div class="list-group-item">Item 4</div>
<div class="list-group-item">Item 5</div>
<div class="list-group-item">Item 6</div>
</div>

swiper.js i want the scrolling to stop at end of the section and stop scrolling to next slide on its own, then continue to normal scrolling

<body>
<div class="swiper swiper1">
<!-- Additional required wrapper -->
<div class="swiper-wrapper">
<!-- Slides -->
<div class="swiper-slide">Slide 1</div>
<div class="swiper-slide">Slide 2</div>
<div class="swiper-slide">Slide 3</div>
</div>
</div>
<div class="newContainer">
<div class="container-wrapper">
<!-- Slides -->
<div class="container-slide">Slide 1</div>
<div class="container-slide">Slide 2</div>
<div class="container-slide">Slide 3</div>
</div>
</div>
</body>
const swiper1 = new Swiper('.swiper1', {
// Optional parameters
direction: 'vertical',
loop: false,
speed: 1000,
preventInteractionOnTransition: true,
mousewheel: {
invert: false,
releaseOnEdges: true,
sensitivity: 0
}
});
swiper.js library
Codepen Link: https://codepen.io/aldrinbright/pen/PoQqgjg
I want the scrolling to stop at Slide 3 and stop scrolling to next slide on its own, then continue to normal scrolling
It is hard to understand exactly what is your desire result.
Anyway by the API this how you dedect slide number 3.
swiper1.on('slideChange', function () {
if(this.activeIndex == "2"){
console.log("slide 3 active");
/* do something */
}
});
Maybe it is helpful.

Is it possible to change the direction vertical slider in swiper slider? I want to have both top to bottom and bottom to top option?

I'm working on a page that contains two vertical sliders. But on clicking down arrow button or on mouse scroll, I want one to slide up words (bottom to top) and the other downwards (top to bottom). How can I implement this?
My code basically looks something like this:
<div class="swiper-container">
<div class="swiper-wrapper">
<div class="swiper-slide">
<div class="swiper-container swiper-container-v swiper-left">
<div class="swiper-pagination swiper-pagination-v"></div>
<div class="swiper-wrapper">
<div class="swiper-slide">Vertical Slide 1</div>
<div class="swiper-slide">Vertical Slide 2</div>
<div class="swiper-slide">Vertical Slide 3</div>
<div class="swiper-slide">Vertical Slide 4</div>
<div class="swiper-slide">Vertical Slide 5</div>
</div>
</div>
<div class="swiper-container swiper-container-v2 swiper-right">
<div class="swiper-wrapper">
<div class="swiper-slide">Vertical Slide 1</div>
<div class="swiper-slide">Vertical Slide 2</div>
<div class="swiper-slide">Vertical Slide 3</div>
<div class="swiper-slide">Vertical Slide 4</div>
<div class="swiper-slide">Vertical Slide 5</div>
</div>
</div>
</div>
</div>
<!-- Add Pagination -->
<div class="swiper-pagination"></div>
</div>
Script like this:
var swiper = new Swiper('.swiper-container', {
direction: 'vertical',
});
var swiperV = new Swiper('.swiper-container-v', {
direction: 'vertical',
spaceBetween: 50,
keyboard: {
enabled: true,
},
pagination: {
el: '.swiper-pagination-v',
clickable: true,
},
loop: true,
});
var swiperV2 = new Swiper('.swiper-container-v2', {
direction: 'vertical',
spaceBetween: 50,
keyboard: {
enabled: true,
},
pagination: {
el: '.swiper-pagination-v',
clickable: true,
},
loop: true,
reverseDirection: true
});
If you are using this swiper there is the navigation object you need to add to your configuration.
Something like in the example the guys that are developing the Swiper are reporting in their API:
var mySwiper = new Swiper('.swiper-container', {
navigation: {
nextEl: '.swiper-button-next',
prevEl: '.swiper-button-prev'
}
});
If you want to invert the standard swiping (direction of swipe) you just need to swap the classes that reference your arrows in the configuration.
var mySwiper = new Swiper('.swiper-container', {
navigation: {
nextEl: '.swiper-button-prev',
prevEl: '.swiper-button-next'
}
});

Swiper Slider puts all slides in one slide

I set up Swiper Slider as per the documentation and every slide slides as if one.
<div class="swiper-container">
<div class="swiper-wrapper">
<div class="swiper-slide">Slide 1</div>
<div class="swiper-slide">Slide 2</div>
<div class="swiper-slide">Slide 3</div>
</div>
</div>
var mySwiper = new Swiper('.swiper-container', {
direction: 'horizontal',
slidesPerView: 1,
});
I also tested it on CodePen with the same result, so I know it's not something in my project: https://codepen.io/DasRollo/pen/YzzMrgP
Can anyone replicate this?
I had the same problem. In my case I added:
import '../../../node_modules/swiper/css/swiper.min.css';
And it's working.
In my case problem was that I didnt add swiper-slide class for each slider item, so solutiom was just add swiper-slide class
<div class="swiper-container">
<div class="swiper-wrapper">
<div class="swiper-slide">Slide 1</div> // add "swiper-slide" class!
<div class="swiper-slide">Slide 2</div> // add "swiper-slide" class!
<div class="swiper-slide">Slide 3</div> // add "swiper-slide" class!
</div>
</div>
My swiper settings after npm install swiper
import Swiper, {Navigation} from 'swiper';
import 'swiper/swiper-bundle.css';
Swiper.use([Navigation]);
const swiper = new Swiper('.swiper-container', {
breakpoints: {
768: {
slidesPerView: 2,
},
1440: {
slidesPerView: 3
},
},
navigation: {
nextEl: '.swiper-button-next',
prevEl: '.swiper-button-prev',
},
slidesPerView: 1,
});
If you use webpack check css loaders
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
},
i was missing ----> import "swiper/css";
In your codepen you forgot to include the css that the plugin also needs to function properly. Not entirely sure if that's what you meant you issue was, but if so, try the code below.
var mySwiper = new Swiper('.swiper-container', {
direction: 'horizontal',
slidesPerView: 1,
});
.swiper-slide {
padding: 2em;
border: 1px solid #ccc;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Swiper/4.5.1/js/swiper.min.js"></script>
<link href="https://unpkg.com/swiper/css/swiper.min.css" rel="stylesheet"/>
<div class="swiper-container">
<!-- Additional required wrapper -->
<div class="swiper-wrapper">
<!-- Slides -->
<div class="swiper-slide">Slide 1</div>
<div class="swiper-slide">Slide 2</div>
<div class="swiper-slide">Slide 3</div>
</div>
<!-- If we need pagination -->
<div class="swiper-pagination"></div>
<!-- If we need navigation buttons -->
<div class="swiper-button-prev"></div>
<div class="swiper-button-next"></div>
<!-- If we need scrollbar -->
<div class="swiper-scrollbar"></div>
</div>
⚠️⚠️⚠️
Slides can missbehave, resulting into beeing on side 1, if you change their width.
In my example i set the width to 150px. All slides were on side 1. There were 9x additional empty sides. I inspected the slides and saw their automatic set width was crossed. Uncrossing it fixed the problem.
Maybe you also set width on them.
Maybe you set a additonal class on the div element, which sets the width:
I had to set navigation despite I did not need it:
navigation: {
prevEl: null,
nextEl: null,
},

Categories

Resources