Swiper pagination, trigger js code on specific slide - javascript

I'm using SwiperJS for sliders.
I was wondering if it's possible to set trigger js code on specific slide in Swiper?
For example, if the user is on second slide the background changes, it triggers JS code getElementById("body");element.classList.add("some-class");
This should also work with arrows, so maybe the question should be,

There's a bunch of events that comes with SwipeJS out of the box.
You can check swiper.realIndex after slideChange event to trigger something only on specific slide.
const swiper = new Swiper('.swiper-container', {
// If we need pagination
pagination: {
el: '.swiper-pagination',
},
// Navigation arrows
navigation: {
nextEl: '.swiper-button-next',
prevEl: '.swiper-button-prev',
},
// And if we need scrollbar
scrollbar: {
el: '.swiper-scrollbar',
},
});
// Do something on slide #2 (note that index starts from 0)
swiper.on('slideChange', (sw) => {
if (sw.realIndex === 1) {
console.log(`Message seen only after changing to slide #${swiper.realIndex + 1}`);
}
});
.slide {
height: 100px;
display: flex;
align-items: center;
justify-content: center;
font-size: 4rem;
}
.slide-1 {
background-color: lightgreen;
}
.slide-2 {
background-color: pink;
}
.slide-3 {
background-color: lightblue;
}
<link rel="stylesheet" href="https://unpkg.com/swiper/swiper-bundle.min.css" />
<script src="https://unpkg.com/swiper/swiper-bundle.min.js"></script>
<!-- Slider main container -->
<div class="swiper-container">
<!-- Additional required wrapper -->
<div class="swiper-wrapper">
<!-- Slides -->
<div class="swiper-slide">
<div class="slide slide-1">1</div>
</div>
<div class="swiper-slide">
<div class="slide slide-2">2</div>
</div>
<div class="swiper-slide">
<div class="slide slide-3">3</div>
</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>

Related

Questions about using Swiper?

I have a problem, my English is not very good, but I try to fully describe the problem I encountered~
I currently use swiper and lightbox2 to make carousel effects, and I still don’t know if I repeatedly watch the official documents. Where is the problem?
There are three questions in total:
Why does the Swiper arrow keys not work?
If you want to keep the picture at 16:9, are there other settings besides setting the width and height?
In addition, why is my direction? The key is always in the middle, not in the middle of the picture?
Thank you everyone for watching my question. I hope you can get help. Thank you again for your assistance.
[
var swiper = new Swiper('.swiper-container', {
direction: 'horizontal',
slidesPerView: 1,
spaceBetween: 4,
breakpointsInverse: true,
breakpoints: {
//当宽度大于等于320
320: {
slidesPerView: 2,
spaceBetween: 10
},
//当宽度大于等于480
480: {
slidesPerView: 3,
spaceBetween: 20
},
//当宽度大于等于640
640: {
slidesPerView: 3,
spaceBetween:24
}
}
})
.swiper-slide img{
width: 375px;
height: 275px;
object-fit: cover;
}
#media(min-width:600px){
.swiper-slide img{
width: 240px;
height: 135px;
object-fit: cover;
}
}
img{
width: 100%;
}
<script src="https://unpkg.com/swiper#7/swiper-bundle.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lightbox2/2.11.3/js/lightbox.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/lightbox2/2.11.3/css/lightbox.css" rel="stylesheet"/>
<link href="https://cdnjs.cloudflare.com/ajax/libs/Swiper/7.0.9/swiper-bundle.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="demo">
<div class="swiper-container">
<div class="swiper-wrapper">
<div class="swiper-slide">
<a href="https://upload.cc/i1/2021/10/20/cO8Cbn.jpg" data-lightbox="banner1" data-title="1">
<img src="https://upload.cc/i1/2021/10/20/cO8Cbn.jpg" alt="">
</a>
</div>
<div class="swiper-slide">
<a href="https://upload.cc/i1/2021/10/20/1NYZ0y.jpg" data-lightbox="banner1" data-title="1">
<img src="https://upload.cc/i1/2021/10/20/1NYZ0y.jpg" alt="">
</a>
</div>
<div class="swiper-slide">
<a href="https://upload.cc/i1/2021/10/22/xAOuwi.jpg" data-lightbox="banner1" data-title="1">
<img src="https://upload.cc/i1/2021/10/22/xAOuwi.jpg" alt="">
</a>
</div>
</div>
<!-- 如果需要分页器 -->
<div class="swiper-pagination"></div>
<!-- 如果需要导航按钮 -->
<div class="swiper-button-prev"></div>
<div class="swiper-button-next"></div>
</div>
</div>

Add prev/next buttons to scroll container with CSS and jQuery

After a long research I found a solution to add a custom scrollbar to a DIV element.
It's called SimpleBar. Docs can be found here.
The HTML structure and JS code is pretty simple:
Working demo
<div class="gallery" data-simplebar data-simplebar-auto-hide="false">
<div class="item"><img src="https://via.placeholder.com/250x150/0000FF" /></div>
<div class="item"><img src="https://via.placeholder.com/350x150/FF0000" /></div>
[...]
</div>
With data-simplebar I can add a custom scrollbar to any DIV.
There is just one thing I couldn't solve.
I want to add prev/next arrows to the scroll element.
The buttons should jump to the prev/next element in the DIV which is next to the left/right side of the div and not yet scrolled (partially) over.
And the JS should work for every slider instance on the site. Like the SimpleBar itself. There is no need for extra code per scroll container.
Is there anything I could use in jQuery?
EDIT: I found this answer and fiddle. I added the code to my example and changed it to left/right. It's not exactly what I need but I thought it could be a starting point. Unfortunately it doesn't work properly.
You can use the following code. Note that the scrolling depends on the viewport, so that once there's no more right width to go to, it won't have more room to move.
const DIRECTION = { PREV: 1, NEXT: 2 };
$(document).ready(function () {
$('.container').each(function (index, containerItem) {
var $gallery = $(containerItem).find('.gallery');
const simpleBar = new SimpleBar($gallery[0], {
autoHide: false,
scrollbarMaxSize: 50
});
var $scroller = $(simpleBar.getScrollElement());
$(containerItem).find('.scrollLeft').on('click', function () {
scroll(DIRECTION.PREV, $scroller);
event.preventDefault(); // prevents anchor jump on click
});
$(containerItem).find('.scrollRight').on('click', function () {
scroll(DIRECTION.NEXT, $scroller);
event.preventDefault();
});
$scroller.scroll(function () {
setButtonsVisibility($scroller);
});
});
});
function scroll(direction, $scroller) {
var $active = $scroller.find('.active');
var $target = direction == DIRECTION.PREV ? $active.prev() : $active.next();
if ($target.length) {
$scroller.animate({
scrollLeft: $target[0].offsetLeft
}, 2000);
$active.removeClass('active');
$target.addClass('active');
}
}
function setButtonsVisibility($scroller) {
var scrollLeft = $scroller.scrollLeft();
isScrollerStart($scroller, scrollLeft);
isScrollerEnd($scroller, scrollLeft);
}
function isScrollerStart($scroller, scrollLeft, $button) {
var $prevButton = $scroller.closest('.container').find('.scrollLeft');
if (scrollLeft == 0) {
$prevButton.css('visibility', 'hidden');
} else {
$prevButton.css('visibility', 'visible');
}
}
function isScrollerEnd($scroller, scrollLeft) {
var $nextButton = $scroller.closest('.container').find('.scrollRight');
var scrollWidth = $scroller[0].scrollWidth; // entire width
var scrollerWidth = $scroller.outerWidth() // visible width
if (scrollLeft >= scrollWidth - scrollerWidth) {
$nextButton.css('visibility', 'hidden');
} else {
$nextButton.css('visibility', 'visible');
}
}
.container {margin: 0 auto 2rem; max-width: 960px;}
.gallery {padding-bottom: 2rem; margin-bottom: 2rem;}
.gallery .simplebar-content {display: flex;}
.gallery .item {margin-right: 1rem;}
.simplebar-scrollbar:before {background: red !important;}
.simplebar-track.simplebar-horizontal {background: #eee !important;;}
.buttons {display: flex; justify-content: space-between; width: 100%; margin-bottom: 2rem;}
.buttons a {padding: 0.5rem; background: #ddd; text-decoration: none; color: #000;}
.scrollLeft { visibility: hidden; }
<script src="https://unpkg.com/simplebar#latest/dist/simplebar.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://unpkg.com/simplebar#latest/dist/simplebar.css">
<div class="container">
<h2>Slider</h2>
<div class="gallery">
<div class="item active"><img src="https://via.placeholder.com/150x30/110000" /></div>
<div class="item"><img src="https://via.placeholder.com/450x30/3300FF" /></div>
<div class="item"><img src="https://via.placeholder.com/350x30/992244" /></div>
<div class="item"><img src="https://via.placeholder.com/400x30/0000FF" /></div>
</div>
<div class="buttons">
<a class="scrollLeft" href="#"><strong>Prev</strong> (remove if first)</a>
<a class="scrollRight" href="#"><strong>Next</strong> (remove if last)</a>
</div>
</div>
<div class="container">
<h2>Slider</h2>
<div class="gallery">
<div class="item active"><img src="https://via.placeholder.com/150x30/110000" /></div>
<div class="item"><img src="https://via.placeholder.com/450x30/3300FF" /></div>
<div class="item"><img src="https://via.placeholder.com/350x30/992244" /></div>
<div class="item"><img src="https://via.placeholder.com/400x30/0000FF" /></div>
</div>
<div class="buttons">
<a class="scrollLeft" href="#"><strong>Prev</strong> (remove if first)</a>
<a class="scrollRight" href="#"><strong>Next</strong> (remove if last)</a>
</div>
</div>

Vue with Muuri - how to use?

I'm very new to Vue and my web dev skills are very limited, so sorry if this is a basic questions.
I just wanted to explore how I could create a draggable grid interface in the browser and found the Muuri package.
Now just following the example code in plain JavaScript/HTML the demo works as expected.
Now I try it with Vue, I get an error saying -
"TypeError: Cannot read property 'getRootNode' of null"
Here is my Vue component that should use Muuri.
<template>
<div class="grid">
<div class="item">
<div class="item-content">
<!-- Safe zone, enter your custom markup -->
This can be anything.
<!-- Safe zone ends -->
</div>
</div>
<div class="item">
<div class="item-content">
<!-- Safe zone, enter your custom markup -->
<div class="my-custom-content">
Yippee!
</div>
<!-- Safe zone ends -->
</div>
</div>
</div>
</template>
<script>
import 'web-animations-js';
import Muuri from 'muuri';
export default {
name: 'Grid',
created() {
var grid = new Muuri('.grid', {dragEnabled:true});
console.log(grid.toString());
}
}
</script>
<style scoped>
.grid {
position: relative;
}
.item {
display: block;
position: absolute;
width: 100px;
height: 100px;
margin: 5px;
z-index: 1;
background: #000;
color: #fff;
}
.item.muuri-item-dragging {
z-index: 3;
}
.item.muuri-item-releasing {
z-index: 2;
}
.item.muuri-item-hidden {
z-index: 0;
}
.item-content {
position: relative;
width: 100%;
height: 100%;
}
</style>
Any help or advice much appreciated!
Your problem is likely that the DOM hasn't loaded when the created event hook gets executed. You could try using mounted instead. I've included a snippet.
new Vue({
el: "#app",
mounted() {
var grid = new Muuri('.grid', {dragEnabled:true});
alert(grid.toString());
}
});
<script src="https://unpkg.com/web-animations-js#2.3.2/web-animations.min.js"></script>
<script src="https://unpkg.com/muuri#0.8.0/dist/muuri.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app" class="grid">
<div class="item">
<div class="item-content">
<!-- Safe zone, enter your custom markup -->
This can be anything.
<!-- Safe zone ends -->
</div>
</div>
<div class="item">
<div class="item-content">
<!-- Safe zone, enter your custom markup -->
<div class="my-custom-content">
Yippee!
</div>
<!-- Safe zone ends -->
</div>
</div>
</div>

Center align boxes inside DIV

I got the following box design.
These green color boxes are dynamically generated inside "col-md-10" div. In the second row, if there is no 3 boxes I want to center align the boxes. In the following case I want to have "Bi-monthly" box right underneath "Weekly" box.
<div class='col-md-10 text-center'>
<div class='col-md-4 text-center'>1</div>
<div class='col-md-4 text-center'>1</div>
<div class='col-md-4 text-center'>1</div>
<div class='text-center center-block' style='width: 33.33333333%;'>1</div>
</div>
This is something I have done using bootstrap 3.x. This works fine. You cannot have the class name col-md-4 for the 4th block. Try this. It works.
In this example, text-center and center-block are bootstrap classes.
Also, try to minimize the use of inline styles. Because, in bootstrap, there are built-in class names for all these things. If you are using bootstrap, make use of it completely.
Cheers
You said
These green color boxes are dynamically generated inside "col-md-10" div
So you need to check condition your dynamic data length , I hope you want to display 3 block in a row then if there is one block in a row you want to set in center . You need to check dynamic data length and divisible 3 to check that can be a single block ....
In below I used col-xs-4 because stackoverfow snippet display is too small ....
var data = ['One','Two','Three','Four'];
var last = data.length - 1;
data.forEach((v,i) => {
var div = "<div class='col-sm-6 col-xs-4 col-md-4 bg-info '>"+v+"</div>";
if((last == i) && (i % 3 == 0)) {
div = "<div class='col-xs-offset-4 col-sm-6 col-xs-4 col-md-4 bg-info '>"+v+"</div>";
}
$(".test .row").append(div);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<!-- Optional theme -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<div class="container">
<div class="row">
<div class="col-md-10 test"><div class="row"></div></div>
</div>
</div>
Did you mean this?
<article class="col-md-12">
<div class="col-lg-3 col-md-3 col-sm-3 col-xs-6 img">...</div>
<div class="col-lg-3 col-md-3 col-sm-3 col-xs-6 img">...</div>
</article>
article{
text-align:center;
}
article .img{
display: inline-block;
float: none;
vertical-align: text-top;
}
Please try to see if this can help you.
I understand you are using Bootstrap.
But you can approach this very elegantly and concisely using CSS Flexbox.
Working Example:
ul {
display: flex;
justify-content: center;
flex-wrap: wrap;
margin: 0 0 60px;
padding: 0;
list-style-type: none;
}
li {
flex: 0 0 calc(33vw - 36px);
margin: 6px;
padding: 6px;
text-align: center;
border: 1px solid rgb(191, 191, 191);
}
<h1>Keep Scrolling down...</h1>
<ul>
<li>One-off</li>
<li>Weekly</li>
<li>Fortnightly</li>
<li>Bi-monthly</li>
</ul>
<ul>
<li>One-off</li>
<li>Weekly</li>
<li>Fortnightly</li>
<li>Bi-monthly</li>
<li>Quarterly</li>
</ul>
<ul>
<li>One-off</li>
<li>Weekly</li>
<li>Fortnightly</li>
<li>Bi-monthly</li>
<li>Quarterly</li>
<li>Half-yearly</li>
</ul>
Use this code
<div class='col-md-10 text-center'>
<div class='col-md-4 text-center'>1</div>
<div class='col-md-4 text-center'>1</div>
<div class='col-md-4 text-center'>1</div>
<div class='col-md-4 offset-md-4'>1</div>
</div>

How can we make different padding top and bottom values for diff sections in fullPage.js?

Normally in fullpage.js we can set single global
paddingTop, paddingBottom value via below code:
$('#fullpage').fullpage({
paddingTop: '130px',
paddingBottom: '50px',
});
My question is can we assign multiple paddingTop,paddingBottom values to individual scroll sections TO achieve more flexible layout display?
$(document).ready(function() {
$('#fullpage').fullpage({
anchors: ['firstPage', 'secondPage'],
sectionsColor: ['#4A6FB1', '#939FAA'],
scrollOverflow: true,
sectionSelector: '.section',
slideSelector: '.slide',
slidesNavigation: true,
slidesNavPosition: 'bottom',
verticalCentered: false,
resize: false,
autoScrolling: true,
paddingTop: '130px',
paddingBottom: '50px'
});
});
.slider-container {
width: 50%;
}
.title-text {
font-size: 30px;
font-weight: bold;
}
p {
line-height: 3em;
}
.contentline { border:1px solid white; }
#demo {
position: absolute;
top: 50px;
margin: 0;
left: 0;
right: 0;
text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://alvarotrigo.com/fullPage/vendors/jquery.slimscroll.min.js"></script>
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/js/bootstrap.min.js"></script>
<link href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" rel="stylesheet"/>
<link href="http://alvarotrigo.com/fullPage/jquery.fullPage.css" rel="stylesheet"/>
<script src="http://alvarotrigo.com/fullPage/jquery.fullPage.min.js"></script>
<div id="fullpage">
<div class="section">
<div class="container slider-container">
<div class="row margin-0" id="demo">
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12 padding-0">
<div class="title-text">padding:130px,bottom:80px layout</div>
</div>
</div>
<div class="slide contentline" id="slide1" data-anchor="s1">
<div class="row margin-0">
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12 padding-0">
<p class="title-text">you may press Arrow Down Key to scroll to the next section </p>
<p>line1</p>
<p>line2</p>
<p>line3</p>
<p>line4</p>
<p>line5</p>
<p>line6</p>
<p>line7</p>
<p>line8</p>
<p>line9</p>
<p>line10</p>
<p>line11</p>
<p>line13</p>
<p>line14</p>
<p>line15</p>
<p>line16</p>
<p>line17</p>
<p>line18</p>
<p>line19</p>
<p>line20</p>
<p>line21</p>
<p>line22</p>
<p>line23</p>
<p>line24</p>
<p>line25</p>
<p>line26</p>
<p>line27</p>
<p>line28</p>
<p>line29</p>
<p>line30</p>
</div>
</div>
</div>
<div class="slide" id="slide2" data-anchor="s2">
slide2
</div>
<div class="slide" id="slide3" data-anchor="s3">
<p>slide3</p>
</div>
<div class="slide" id="slide4" data-anchor="s4">
<p>slide4</p>
</div>
</div>
<!--end of container-->
</div>
<div class="section title-text">
<div class="contentline">
Some sections<br> which require different<br> paddingTop and padding bottom values<br>
For example this page, if i need paddingTop: 20px; paddingBottom:20px;<br> instead of running global value of 130px 50px;<br>
if using css to override padding,<br>
the calculated slider height is still wrong.
</div>
</div>
</div>
You can override it as suggested by #CraigduToit.
Fullpage.js will read your value as you can see here.
Here's an example of overriding the paddingTop value. I've colored in grey the real content area without the paddings.
I just used:
#section2 {
padding-top: 10px !important;
}
With this initialization:
$('#fullpage').fullpage({
sectionsColor: ['yellow', 'orange', 'purple', '#ADD8E6'],
paddingTop: '100px',
paddingBottom: '100px',
scrollOverflow: true,
});
I believe this can be achieved with css, however it requires you to add (or build upon) a uniuque class for each sections content.
I added a class "testingstuff" to your child div on the second section, so the HTML will be:
<div class="section title-text fp-section active testingstuff">....</div>
And then went on to simply create the class in the .css with the following properties:
.testingstuff{
padding:30px 0px 30px 0px !important;
}
So going forward, all you would need to do is create a class for each section, not the most elegant way to do it, but it is rather quick and easy.
Hope this helps.

Categories