Features & Benefits
- Vanilla Javascript based carousel/ slider.
- Uses Javascript ES6 version based Web Component structure.
- Superfast performance, no third-party framework needed.
- Framework independent, use with any framework (react, angular, etc...).
- Very easy to integrate in any framework.
- Fully responsive. Scales with its container.
- Separate settings per breakpoint.
- Uses CSS3. Fully functional.
- Swipe enabled. Or disabled, if you prefer.
- Desktop mouse dragging.
- Infinite looping.
- Fully accessible with arrow key navigation.
- Add, remove, filter & unfilter slides.
- Autoplay, dots, arrows, callbacks, etc...
Single Item
1
2
3
4
5
<ap-slider>
<div>
<p>1</p>
</div>
<div>
<p>2</p>
</div>
<div>
<p>3</p>
</div>
<div>
<p>4</p>
</div>
<div>
<p>5</p>
</div>
</ap-slider>
Multiple Item
1
2
3
4
5
6
7
8
9
<ap-slider data-apslider='{"draggable": true, "infinite": true, "slidesToShow": 3, "slidesToScroll": 3}'>
<div>
<p>1</p>
</div>
<div>
<p>2</p>
</div>
<div>
<p>3</p>
</div>
<div>
<p>4</p>
</div>
<div>
<p>5</p>
</div>
<div>
<p>6</p>
</div>
<div>
<p>7</p>
</div>
<div>
<p>8</p>
</div>
<div>
<p>9</p>
</div>
</ap-slider>
Rsponsive Display
1
2
3
4
5
6
7
8
<!--
You can destroy/init apslider at a given breakpoint by adding:
settings: "destroyed"
instead of a settings object
-->
<ap-slider
data-apslider='{
"speed": 300,
"slidesToShow": 4,
"slidesToScroll": 4,
"responsive": [{
"breakpoint": 1024,
"settings": {
"slidesToShow": 3,
"slidesToScroll": 3,
"infinite": true
}
},
{
"breakpoint": 600,
"settings": {
"slidesToShow": 2,
"slidesToScroll": 2
}
},
{
"breakpoint": 480,
"settings": {
"slidesToShow": 1,
"slidesToScroll": 1
}
}]
}'>
<div>
<p>1</p>
</div>
<div>
<p>2</p>
</div>
<div>
<p>3</p>
</div>
<div>
<p>4</p>
</div>
<div>
<p>5</p>
</div>
<div>
<p>6</p>
</div>
<div>
<p>7</p>
</div>
<div>
<p>8</p>
</div>
</ap-slider>
Variable Width
200
175
150
300
225
125
<ap-slider
data-apslider='{"dots": true, "infinite": true, "speed": 300, "slidesToShow": 1, "centerMode": true, "variableWidth": true}'>
<div style="width: 200px;">
<p>200</p>
</div>
<div style="width: 200px;">
<p>175</p>
</div>
<div style="width: 200px;">
<p>150</p>
</div>
<div style="width: 200px;">
<p>300</p>
</div>
<div style="width: 200px;">
<p>225</p>
</div>
<div style="width: 200px;">
<p>125</p>
</div>
</ap-slider>
Adaptive Height
1
2
Look ma!
3
Check
this out!
4
Woo!
<ap-slider
data-apslider='{"dots": true, "infinite": true, "speed": 300, "slidesToShow": 1, "adaptiveHeight": true}'>
<div>
<h3>1</h3>
</div>
<div>
<h3>2</h3>
<p>Look ma!</p>
</div>
<div>
<h3>3</h3>
<p>Check
<br />this out!
</p>
</div>
<div>
<h3>4</h3>
<p>Woo!</p>
</div>
</ap-slider>
Settings Options w/Javascript
1
2
3
4
5
6
7
8
9
<!-- HTML Structure -->
<ap-slider class="settings-from-js">
<div>
<p>1</p>
</div>
<div>
<p>2</p>
</div>
<div>
<p>3</p>
</div>
<div>
<p>4</p>
</div>
<div>
<p>5</p>
</div>
<div>
<p>6</p>
</div>
<div>
<p>7</p>
</div>
<div>
<p>8</p>
</div>
<div>
<p>9</p>
</div>
</ap-slider>
/* Javscript Settings */
const carouselElement = document.querySelector('.settings-from-js');
carouselElement.settings = {
slidesToShow: 4,
slidesToScroll: 4
}
carouselElement.reinit(true);
Center Mode
1
2
3
4
5
6
7
8
9
<ap-slider data-apslider='{"infinite": true, "centerMode": true, "slidesToShow": 3}'>
<div>
<p>1</p>
</div>
<div>
<p>2</p>
</div>
<div>
<p>3</p>
</div>
<div>
<p>4</p>
</div>
<div>
<p>5</p>
</div>
<div>
<p>6</p>
</div>
<div>
<p>7</p>
</div>
<div>
<p>8</p>
</div>
<div>
<p>9</p>
</div>
</ap-slider>
Lazy Loading
<ap-slider data-apslider='{"lazyLoad": "ondemand", "slidesToScroll": 2, "slidesToShow": 2}'>
<div><img data-lazy="https://picsum.photos/200/100?random=1"></div>
<div><img data-lazy="https://picsum.photos/200/100?random=2"></div>
<div><img data-lazy="https://picsum.photos/200/100?random=3"></div>
<div><img data-lazy="https://picsum.photos/200/100?random=4"></div>
<div><img data-lazy="https://picsum.photos/200/100?random=5"></div>
<div><img data-lazy="https://picsum.photos/200/100?random=6"></div>
<div><img data-lazy="https://picsum.photos/200/100?random=7"></div>
<div><img data-lazy="https://picsum.photos/200/100?random=8"></div>
<div><img data-lazy="https://picsum.photos/200/100?random=9"></div>
</ap-slider>
Autoplay
1
2
3
4
5
6
<ap-slider data-apslider='{"autoplay": true, "autoplaySpeed": 2000, "slidesToScroll": 1, "slidesToShow": 3}'>
<div>
<p>1</p>
</div>
<div>
<p>2</p>
</div>
<div>
<p>3</p>
</div>
<div>
<p>4</p>
</div>
<div>
<p>5</p>
</div>
<div>
<p>6</p>
</div>
</ap-slider>
Fade
<ap-slider data-apslider='{"infinite": true, "speed": 500, "fade": true, "cssEase": "linear"}'>
<div><img src="https://picsum.photos/200/100?random=1"></div>
<div><img src="https://picsum.photos/200/100?random=2"></div>
<div><img src="https://picsum.photos/200/100?random=3"></div>
<div><img src="https://picsum.photos/200/100?random=4"></div>
<div><img src="https://picsum.photos/200/100?random=5"></div>
</ap-slider>
Add & Remove Slide
1
const carouselAddRemove = document.querySelector('.add-remove');
const buttons = document.querySelectorAll('button');
let slideIndex = 1;
buttons.forEach(button => {
button.addEventListener('click', (e) => {
if (e.target.classList.contains('add')) {
slideIndex++;
const elWrapper = document.createElement('div');
const el = document.createElement('p');
el.innerText = slideIndex;
elWrapper.append(el);
carouselAddRemove.addSlide(elWrapper);
}
if (e.target.classList.contains('remove')) {
carouselAddRemove.removeSlide(slideIndex - 1);
if (slideIndex !== 0) slideIndex--;
}
});
});
Filtering
1
2
3
4
5
6
7
8
9
const carouselFilter = document.querySelector('.js-filter');
const buttons = document.querySelectorAll('button');
buttons.forEach(button => {
button.addEventListener('click', (e) => {
if (e.target.classList.contains('filter')) {
carouselFilter.filterSlides(':odd');
}
if (e.target.classList.contains('unfilter')) {
carouselFilter.unFilterSlides();
}
});
});
Destroy
1
2
3
<ap-slider class="destroy-init" data-no-init="true">
<div>
<p>1</p>
</div>
<div>
<p>2</p>
</div>
<div>
<p>3</p>
</div>
</ap-slider>
const carouselReInit = document.querySelector('.destroy-init');
const buttons = document.querySelectorAll('button');
buttons.forEach(button => {
button.addEventListener('click', (e) => {
if (e.target.classList.contains('init')) {
carouselReInit.init();
}
if (e.target.classList.contains('destroy')) {
carouselReInit.destroy(true);
}
});
});
Slider Syncing
1
2
3
4
5
1
2
3
4
5
<ap-slider class="syncing slider-for" data-apslider='{"slidesToShow": 1, "slidesToScroll": 1, "arrows": false, "fade": true, "asNavFor": ".slider-nav"}'>
<div>
<p>1</p>
</div>
<div>
<p>2</p>
</div>
<div>
<p>3</p>
</div>
<div>
<p>4</p>
</div>
<div>
<p>5</p>
</div>
</ap-slider>
<ap-slider class="syncing slider-nav" data-apslider='{"infinite": true, "slidesToShow": 3, "slidesToScroll": 1, "asNavFor": ".slider-for", "dots": true, "centerMode": true, "focusOnSelect": true}'>
<div>
<p>1</p>
</div>
<div>
<p>2</p>
</div>
<div>
<p>3</p>
</div>
<div>
<p>4</p>
</div>
<div>
<p>5</p>
</div>
</ap-slider>
Right to Left
1
2
3
4
5
<ap-slider dir="rtl" data-apslider='{"rtl": true}'>
<div>
<p>1</p>
</div>
<div>
<p>2</p>
</div>
<div>
<p>3</p>
</div>
<div>
<p>4</p>
</div>
<div>
<p>5</p>
</div>
</ap-slider>
Note: the HTML tag or the parent of the slider must have the attribute "dir" set to "rtl".
and a whole lot more...
Getting Started
Set up your HTML markup.
<ap-slider class="YOUR_CLASS">
<p>1</p>
<p>2</p>
<p>3</p>
<p>4</p>
<p>5</p>
</ap-slider>
Move the /apslider
folder into your project
Add `css` file to you <head />
<link type="text/css" src="./apslider/apslider.css"></link>
Add apslider.js
before your closing <body />
tag
<script type="text/javascript" src="./apslider/apslider.min.js"></script>
When complete, your HTML should look something like:
<html>
<head>
<title>Javascript Carousel</title>
<link type="text/css" src="./apslider/apslider.css"></link>
</head>
<body>
<ap-slider class="your-class">
<div>your content</div>
<div>your content</div>
<div>your content</div>
</ap-slider>
<script type="text/javascript" src="./apslider/apslider.min.js"></script>
</body>
</html>
Settings
accessibility
boolean
true
Enables tabbing and arrow key navigation.
adaptiveHeight
boolean
false
Enables adaptive height for single slide horizontal carousels.
autoplay
boolean
false
Enables Autoplay.
autoplaySpeed
int(ms)
3000
Autoplay Speed in milliseconds.
arrows
boolean
true
Prev/Next Arrows.
asNavFor
string
null
Set the slider to be the navigation of other slider (Class or ID Name).
appendArrows
string
document.querySelector(element)
Change where the navigation arrows are attached (Selector, htmlString, Array, Element).
appendDots
string
document.querySelector(element)
Change where the navigation dots are attached (Selector, htmlString, Array, Element).
prevArrow
string (html selector) | object (DOM node)
<button class="apslider-prev" aria-label="Previous" type="button">Previous</button>
Allows you to select a node or customize the HTML for the "Previous" arrow.
nextArrow
string (html selector) | object (DOM node)
<button class="apslider-next" aria-label="Next" type="button">Next</button>
Allows you to select a node or customize the HTML for the "Next" arrow.
centerMode
boolean
false
Enables centered view with partial prev/next slides. Use with odd numbered slidesToShow counts.
centerPadding
string
'50px'
Side padding when in center mode (px or %).
cssEase
string
'ease'
CSS3 Animation Easing.
customPaging
function
n/a
Custom paging templates. See source for use example.
dots
boolean
false
Show dot indicators.
dotsClass
string
'apslider-dots'
Class for slide indicator dots container.
draggable
boolean
true
Enable mouse dragging.
fade
boolean
false
Enable fade.
focusOnSelect
boolean
false
Enable focus on selected element (click).
easing
string
'linear'
Add easing for jQuery animate. Use with easing libraries or default easing methods.
edgeFriction
integer
0.15
Resistance when swiping edges of non-infinite carousels.
infinite
boolean
true
Infinite loop sliding.
initialSlide
integer
0
Slide to start on.
lazyLoad
string
'ondemand'
Set lazy loading technique. Accepts 'ondemand' or 'progressive'.
mobileFirst
boolean
false
Responsive settings use mobile first calculation.
pauseOnFocus
boolean
true
Pause Autoplay On Focus.
pauseOnHover
boolean
true
Pause Autoplay On Hover.
pauseOnDotsHover
boolean
false
Pause Autoplay when a dot is hovered.
respondTo
string
'window'
Width that responsive object responds to. Can be 'window', 'slider' or 'min' (the smaller of the two).
responsive
object
none
Object containing breakpoints and settings objects (see demo). Enables settings sets at given screen width. Set settings to "destroyed" instead of an object to disable apslider at a given breakpoint.
rows
int
1
Setting this to more than 1 initializes grid mode. Use slidesPerRow to set how many slides should be in each row.
slide
element
''
Element query to use as slide.
slidesPerRow
int
1
With grid mode intialized via the rows option, this sets how many slides are in each grid row.
slidesToShow
int
1
# of slides to show.
slidesToScroll
int
1
# of slides to scroll.
speed
int(ms)
300
Slide/Fade animation speed.
swipe
boolean
true
Enable swiping.
swipeToSlide
boolean
false
Allow users to drag or swipe directly to a slide irrespective of slidesToScroll.
touchMove
boolean
true
Enable slide motion with touch.
touchThreshold
int
5
To advance slides, the user must swipe a length of (1/touchThreshold) * the width of the slider.
variableWidth
boolean
false
Variable width slides.
vertical
boolean
false
Vertical slide mode.
verticalSwiping
boolean
false
Vertical swipe mode.
rtl
boolean
false
Change the slider's direction to become right-to-left.
waitForAnimate
boolean
true
Ignores requests to advance the slide while animating.
zIndex
number
1000
Set the zIndex values for slides, useful for IE9 and lower.
Events
Each of the event will have `event.detail` object. This `event.detail` object will have values from respective events. In below example, we can see that the `event.detail` has been destructured so in the callback function we can call it directly with it's name.
const carousel = document.querySelector('.your-element');
// On swipe event
carousel.addEventListener('swipe', ({ detail: { apslider, direction } }) => {
console.log(direction);
// Output: left
});
// On edge hit
carousel.addEventListener('edge', ({ detail: { apslider, direction } }) => {
console.log('edge was hit')
});
// On before slide change
carousel.addEventListener('beforeChange', ({ detail: { apslider, currentSlide, nextSlide } }) => {
console.log(nextSlide);
});
afterChange
{ detail: { apslider, currentSlide } }
Fires after slide change.
beforeChange
{ detail: { apslider, currentSlide, nextSlide } }
Fires after slide change.
breakpoint
{ detail: { apslider, breakpoint } }
Fires after a breakpoint is hit.
destroyed
{ detail: { apslider } }
When slider is destroyed.
edge
{ detail: { apslider, direction } }
Fires when an edge is overscrolled in non-infinite mode.
init
{ detail: { apslider } }
Fires after first initialization.
reInit
{ detail: { apslider } }
Fires after every re-initialization.
setPosition
{ detail: { apslider } }
Fires after position/size changes.
swipe
{ detail: { apslider, direction } }
Fires after swipe/drag.
lazyLoaded
{ detail: { apslider, image, imageSource } }
Fires after image loads lazily.
lazyLoadError
{ detail: { apslider, image, imageSource } }
Fires after image fails to load.
Methods
Methods are called on apslider instances through the apslider's method itself, see below:
const carousel = document.querySelector('.your-element');
// Add a slide
carousel.addSlide("<div>COTNENT</div>");
// Get the current slide
const currentSlide = carousel.getCurrentSlide();
// Manually refresh positioning of carousel
carousel.setPosition();
getCurrentSlide
none
Returns the current slide index.
goTo
int: slide number, boolean: dont animate
Navigates to a slide by index.
next
none
Navigates to the next slide.
prev
none
Navigates to the previous slide.
pause
none
Pauses autoplay.
play
none
Starts autoplay.
addSlide
html or DOM object, index, addBefore
Add a slide. If an index is provided, will add at that index, or before if addBefore is set. If no index is provided, add to the end or to the beginning if addBefore is set. Accepts HTML String || Object.
removeSlide
index, removeBefore
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.
filterSlides
HTML Selector
Filters slides using DOM selector (ex: :odd, :even, className of DOM elements).
unFilterSlides
None
Removes applied filtering.
getOption
option: string
Gets an individual option value.
setOption
option: string, value: depends on option, refresh: boolean
Sets an individual value live. Set refresh to true if it's a UI update.
destroy
none
Deconstructs apslider.
getAPSlider
none
Get apslider Object.
Download
APSlider is a lightweight (only 3kb gzipped) carousel plugin with no dependencies and very basic styling. As I do not want to over burdned css for you, so you can do it yourself. It is 100% open source and available on Github or download it. Use it with your favourite module bundler or by manually injecting the script into your project.