jedliSlider

Fully responsive, modern carousel in pure JS

What is jedliSlider?

IMPORTANT: FOR NOW ONLY THE CONTINUOUS MODE IS FULLY IMPLEMENTED!


jedliSlider is lightweight carousel with multiple options and modes to use on your page, created in pure (vanilla) javascript and css.

Why jedliSlider?

Because it’s easy to use, modern and will have all options that you want. Some popular carousels still use floats and a lot of unnecessary scripts/styles. My intention was to create one slider, that will contain all things i missed in other carousels. With as low code and css as possible. So you don't need to override some default styles and download multiple libraries for specific types of carousels.


advantages of jedliSlider:

  • Modern and fast - slider is build on flexbox, so there is no need to recalculate width of slides on resize, css will do it itself (not for continuous mode)
  • no dependencies
  • no unnecessary styles
  • easy to use
  • You don't have to create structure, slider will do it for you
  • just let me know about things, modes or options you want and i will add them

Compatibility

jedliSlider is built on css flexbox. So will be compatible with every browser that supports flexbox.

Status:

IMPORTANT: FOR NOW ONLY THE CONTINUOUS MODE IS FULLY IMPLEMENTED!

React version: HERE

There are currently two working modes:

  • continuous - fully implemented
  • default - (check available options here

More will be added soon

What's new?

v. 0.13.22
  • Added resize observer to continuous mode when slidesWidth is set to "auto" so the slider will start rotate when width of slides inside change (for example image will be loaded later)


Previous update:
  • Fixed bug with 'auto' width of slides in 'countinous' mode after last update

Features soon:

  • Creating dots from options
  • Creating dots with custom html
  • Lazy load for images
  • Custom animation of changing slides
  • 'Centered' mode, where some slides are bigger, smaller or highlighted by other way, with some levels of highlightness and animation between levels

How to use:

Install via npm

"npm install jedlislider"

jedliSlider at NPM

If you work with webpack

Import slider:

import jedliSlider from 'jedlislider/src-webpack/jedlislider.js'

and import styles (one of this):

  • CSS: import 'jedlislider/dist/jedlislider.bundle.css'
  • SCSS: import 'jedlislider/src-webpack/jedlislider.scss'

If you work without webpack

add this files to your wesbite by script and link tag:

  • JS: jedlislider/src/jedlislider.js
  • And one of this:

  • CSS: jedlislider/dist/jedlislider.bundle.css
  • SCSS: jedlislider/src/jedlislider.scss

Initialization

Simple html structure

                        
<div data-item="slider">
    <div>
        slide 1
    </div>
    <div>
        slide 2
    </div>
    <div>
        slide 3
    </div>
</div>
                        
                    

Examples:

continuous mode, slides to equal, direction right

Slide 1
Slide 2
Slide 3
Slide 4
Slide 5
Slide 6
                        
let sliderContinuousEqual = new jedliSlider(document.querySelector("[data-item='slider-continuous-equal']"), {
    "mode": "continuous",
    "slidesWidth": "equal",
    "visibleSlides": "4",
    "speed": "5",
    "direction": "right",
})
                        
                    

continuous mode, slides to auto, direction left, pauseOnHover true

                            
let sliderContinuousEqualLeft = new jedliSlider(document.querySelector("[data-item='slider-continuous-equal-left']"), {
    "mode": "continuous",
    "slidesWidth": "equal",
    "visibleSlides": "4",
    "speed": "5",
    "direction": "left",
    "pauseOnHover": "true"
})
                            
                        

continuous mode, slides to auto

*resize window and see when slider will start to rotate*
Slide 1
Slide 2
Slide 3
Slide 4
                        
let sliderContinuousAuto = new jedliSlider(document.querySelector("[data-item='slider-continuous-auto']"), {
    "mode": "continuous",
    "slidesWidth": "auto",
    "visibleSlides": "auto",
    "speed": "5",
    "direction": "right",
})
                        
                    

default mode, slidesToScroll 2, preventOverScroll set to true

Slide 1
Slide 2
Slide 3
Slide 4
Slide 5
Slide 6
Slide 7
Slide 8
                        
let sliderDefaultEqual = new jedliSlider(document.querySelector("[data-item='slider-default-equal']"), {
    "mode": "default",
    "slidesWidth": "equal",
    "visibleSlides": 5,
    "easing": "ease-out",
    "slidesToScroll": 2,
    "speed": "600",
    "preventOverScroll": "true",
})

// Nav for sliderDefaultEqual

// Prev slide
document.querySelector("[data-action='slider-default-equal-prev']").addEventListener("click", () => {
    sliderDefaultEqual.slidePrev();
})

// Next slide
document.querySelector("[data-action='slider-default-equal-next']").addEventListener("click", () => {
    sliderDefaultEqual.slideNext();
})

// Go to specific slide
let sliderDefaultEqualGoToSlide = document.querySelector("[data-action='slider-default-equal-to-slide']");
sliderDefaultEqualGoToSlide.addEventListener('click', () => {

    // Get value from input number
    const value = +document.querySelector("[data-item='slider-default-equal-slide-index']").value;

    sliderDefaultEqual.goToSlide(value);
})
                        
                    

default mode, slidesToScroll 2, preventOverScroll set to false

Slide 1
Slide 2
Slide 3
Slide 4
Slide 5
Slide 6
Slide 7
Slide 8
                            
let sliderDefaultEqual = new jedliSlider(document.querySelector("[data-item='slider-default-equal']"), {
    "mode": "default",
    "slidesWidth": "equal",
    "visibleSlides": 5,
    "easing": "ease-out",
    "slidesToScroll": 2,
    "speed": "600",
})

// Nav for sliderDefaultEqual

// Prev slide
document.querySelector("[data-action='slider-default-equal-prev']").addEventListener("click", () => {
    sliderDefaultEqual.slidePrev();
})

// Next slide
document.querySelector("[data-action='slider-default-equal-next']").addEventListener("click", () => {
    sliderDefaultEqual.slideNext();
})
                            
                        

default mode, infinite true

Slide 1
Slide 2
Slide 3
Slide 4
Slide 5
Slide 6
Slide 7
Slide 8
                            
    let sliderDefaultEqualInfinite = new jedliSlider(document.querySelector("[data-item='slider-default-equal-infinite']"), {
        "mode": "default",
        "slidesWidth": "equal",
        "infinite": "true",
        "visibleSlides": 5,
        "easing": "ease-out",
        "slidesToScroll": 2,
        "speed": "600",
        "preventOverScroll": "false",
    })
    
    // Nav for sliderDefaultEqual
    
    // Prev slide
    document.querySelector("[data-action='slider-default-equal-infinite-prev']").addEventListener("click", () => {
        sliderDefaultEqualInfinite.slidePrev();
    })
    
    // Next slide
    document.querySelector("[data-action='slider-default-equal-infinite-next']").addEventListener("click", () => {
        sliderDefaultEqualInfinite.slideNext();
    })
                            
                        

default mode, infinite true, autoplay true, pauseOnHover true

Slide 1
Slide 2
Slide 3
Slide 4
Slide 5
Slide 6
                            
        let sliderDefaultEqualInfiniteAutoplay = new jedliSlider(document.querySelector("[data-item='slider-default-equal-infinite-autoplay']"), {
            "mode": "default",
            "slidesWidth": "equal",
            "infinite": "true",
            "visibleSlides": 5,
            "easing": "ease-out",
            "slidesToScroll": 2,
            "speed": "600",
            "preventOverScroll": "false",
            "autoplay": "true",
            "autoplaySpeed": "2500",
            "pauseOnHover": "true",
        })
                            
                        

default mode, infinite true, generated nav

Slide 1
Slide 2
Slide 3
Slide 4
Slide 5
Slide 6
Slide 7
Slide 8
                            
Basic nav structure:

attr/id/class whatever to get this element
and add to your buttons attr jedli-target with number of slide that you want it to move

<div data-item="example-nav">
    <button jedli-target="1" >
        go to 1
    </button>
    <button jedli-target="2" >
        go to 2
    </button>
    <button jedli-target="3" >
        go to 3
    </button>
</div>

let sliderDefaultEqualInfiniteNav = new jedliSlider(document.querySelector("[data-item='slider-default-equal-infinite-nav']"), {
    "mode": "default",
    "slidesWidth": "equal",
    "infinite": "true",
    "visibleSlides": 5,
    "easing": "ease-out",
    "slidesToScroll": 2,
    "speed": "600",

    OPTIONS FOR NAV
    "generateNav": "true",
    "navContainer": document.querySelector("[data-item='example-nav']"),
})
                            
                        

Catch events

Open console and play with this slider to see effects

Slide 1
Slide 2
Slide 3
Slide 4
Slide 5
Slide 6
                                
*Get block with slider
let sliderEventsContainer = document.querySelector("[data-item='slider-default-events']");

*Catch event init 
*You have to declarate init event before declaration of slider
sliderEventsContainer.addEventListener('init', () => {
    console.log("Init");
})

let sliderEventsInit = new jedliSlider(sliderEventsContainer, {
    "mode": "default",
    "slidesWidth": "equal",
    "infinite": "true",
    "visibleSlides": 5,
    "easing": "ease-out",
    "slidesToScroll": 2,
    "speed": "600",
    "preventOverScroll": "false",
})

*Catch event beforeChange
sliderEventsContainer.addEventListener('beforeChange', () => {
    console.log("Before change");
})

*Catch event afterChange
sliderEventsContainer.addEventListener('afterChange', () => {
    console.log("After change");
})
                                
                            

Fade animation

Slide 1
Slide 2
Slide 3
Slide 4
Slide 5
Slide 6
                                

// Custom easing
let sliderCustomEasing = new jedliSlider(document.querySelector("[data-item='slider-custom-easing']"), {
    "mode": "default",
    "slidesWidth": "equal",
    "infinite": "true",
    "visibleSlides": 1,
    "easing": "ease-out",
    "slidesToScroll": 1,
    "speed": "600",
    "preventOverScroll": "false",

// HERE YOU DECLARATE ANIMATION:
    "animationChange": "fade"
})

document.querySelector("[data-action='slider-custom-easing-prev']").addEventListener("click", () => {
    sliderCustomEasing.slidePrev();
})

// Next slide
document.querySelector("[data-action='slider-custom-easing-next']").addEventListener("click", () => {
    sliderCustomEasing.slideNext();
})
                                
                            

Filtering slides

Slide 1
Slide 2
Slide 3
Slide 4
Slide 5
Slide 6
Slide 7
Slide 8
Slide 9
Slide 10
Slide 11
Slide 12
                                
// Create structure, add attr jedli-category to your slides. For example:

<div data-item="slider">
    <div jedli-category="first-category" >
        slide 1
    </div>
    <div jedli-category="second-category" >
        slide 2
    </div>
    <div jedli-category="first-category" >
        slide 3
    </div>
</div>

// Initialize your slider, there is no need for special options

// And trigger by the way you want function filter() on slider object

"all" to see all slides
YourSlider.filter('all');

YourSlider.filter('first-category');

YourSlider.filter('second-category');

// There is an option to set delay before filtering, so you could add custom animation of change or anything
// Option to set delay:

"filterDelay"

for example: 
"filterDelay": 300,

// Events for filtering

- "beforeFilter"
- "afterFilter"
                                
                            

Events:

beforeInit

afterInit

It's imortant to define eventListener for init events BEFORE initialization of slider

beforeChange

afterChange

dragStart

dragEnd

beforeFilter

afterFilter

Example:

                        
*Catch event init 
*You have to declarate init events before declaration of slider
document.querySelector("[your-slider]").addEventListener('beforeInit', () => {
    console.log("beforeInit");
})

document.querySelector("[your-slider]").addEventListener('afterInit', () => {
    console.log("afterInit");
})

*Catch event beforeChange
document.querySelector("[your-slider]").addEventListener('beforeChange', () => {
    console.log("Before change");
})

*Catch event afterChange
document.querySelector("[your-slider]").addEventListener('afterChange', () => {
    console.log("After change");
})
                        
                    

Functions:

slideNext()

slidePrev()

goToSlide(Here number of slide)

filter(Here category name or "all" to see all slides)

Example:

                        
Define your slider 
let yourSlide = new jedliSlider(document.querySelector("[your-slider']"), {
    options here
})

Go to prev slide or slides if 'slidesToScroll is greater than 1'
yourSlide.slidePrev();

Go to next slide or slides if 'slidesToScroll is greater than 1'
yourSlide.slideNext();

Go to specific slide
yourSlide.goToSlide(value);
                        
                    

Options:

mode

availabile options:
  • default - normal, typical carousel, where you can change slides by arrows or by swap (swap is not working yet)
  • continuous - smooth, infinite animation, going all the time

slidesWidth

availabile options:
  • equal - All slides have same, specified from js size
  • auto - width of every slides can be different, specifed from css, in 'continuous' mode slider will animate if width of all slides is greater than container width (not working in 'default' mode yet)

visibleSlides

availabile options:
  • Any int number greater than 0
  • auto - if slidesWidth is set to 'auto'

slidesToScroll

availabile options:
  • Any int number greater than 0

direction

*Works in 'continuous' mode only* availabile options:
  • left - Make carousel rotate from right to left
  • right - Make carousel rotate from left to right

draggable

*Works in 'default' mode only* availabile options:
  • true
  • false

speed

availabile options:
  • Any int number greater than or equal 0

easing

availabile options:
  • Any CSS3 easing, can be default like 'ease-out' or cubic-bezier

overflow

availabile options:
  • hidden - Add overflow hidden to track container.
  • anything different than hidden (even empty space) - Slider won't have overflow hidden

preventOverScroll

*Works in 'default' mode only* availabile options:
  • true - Slider will recalculate distance to animate when wanted amount of slides to scroll is greater than amount of slides.
    For example: (You are at 4th and 5th slide, there are 6 slides. But your slides to scroll is 2. With this option set to true instead of going 2 slides, slider will move only by 1 slide.
  • false - Slider will not recalculate distance.
    For example: (You are at 4th and 5th slide, there are 6 slides. But your slides to scroll is 2. With this option set to false your slide will move by 2 slides anyway, leaving empty space for missing slides

arrows

*Works in 'default' mode only* availabile options:
  • true - Arrows will be generated, default or custom if 'arrowPrev' or 'arrowNext' is defined
  • false - arrows won't be genreated'

prevArrow/nextArrow

*Works in 'default' mode only* availabile options:
  • Allow to put custom html code as arrow prev. Slider will automatically add attr to handle change. It's necessary to set 'arrows' option to true, to generate custom arrows

infinite

*Works in 'default' mode only* availabile options:
  • true - Set carousel to work as infinite, without end.
  • false - Stop carousel from working as inifnite

autoplay

*Works in 'default' mode only* availabile options:
  • true - Slider will automatically go to next/prev slide after specified time
  • false - Stop autoplay

autoplaySpeed

*Works in 'default' mode only* availabile options:
  • Any int number greater than 0,

autoplayDirection

*Works in 'default' mode only* availabile options:
  • left - after specified time go to next slide
  • right - after specified time go to prev slide

pauseOnHover

availabile options:
  • true - Carousel will stop animation or autoplay on hover, or for accessibility reasons - on focus at any element inside slider
  • false - Slider won't stop on hover

generateNav

*Works in 'default' mode only* availabile options:
  • true
  • false

navContainer

*Works in 'default' mode only* Needs 'generateNav' option set to true availabile options:
  • html element in which slider will look for elements with 'jedli-target' attributes
  • Se example here

animationChange

*Works in 'default' mode only* availabile options:
  • transform (default)
  • fade

filterDelay

*Works in 'default' mode only* availabile options:
  • Any int number grater or equal 0

responsive

Set new options to work from specified breakpoint example:
                        
"responsive": [
    {
        "breakpoint": 992,
        "options": {
            "visibleSlides": 3
        }
    },
    {
        "breakpoint": 768,
        "options": {
            "visibleSlides": 2
        }
    }
]
                        
                    

List of options:

Option: Default: Description:
mode default jedliSlider contain few different modes, types of carousels. Select wanted one. This option define how almost all of other options will work
slidesWidth equal determinate if all slides should be same size, specified by slider; or width of every slides can be different, specifed from css
visibleSlides 1 This option works when "slidesWidth" is set to "equal". Determinate how much slides will be visible
slidesToScroll 1 By how many slides should slider move, on action "nextSlide" or "prevSlide"
draggable true Works only in 'default'mode, turn on/off touch/drag support
speed 400 Transition duration of one single change. In "continuous" mode speed is amount of ms per every single px
easing linear Define easing of slider move animation
overflow hidden Define if slider should have overflow hidden or not
pauseOnHover false Determinate if carousel should stop animation or autoplay on hover, or for accessibility reasons - on focus at any element inside slider
direction left This option works in "continuous" mode. determinate if carousel should rotate from left to right, or right to left
preventOverScroll true This option works in "default" mode. Determinate if slider should recalculate distance to animate when wanted amount of slides to scroll is greater than amount of slides. For example: (You are at 4th and 5th slide, there are 6 slides. But your slides to scroll is 2. With this option set to true instead of going 2 slides, slider will move only by 1 slide.
infinite false This option works in "default" mode. Set carousel to work as infinite, without end.
autoplay false Slider will automatically go to next/prev slide after specified time. Slider will stop change on track hover
autoplaySpeed 1500 Time after next/prev event will be triggered
autoplayDirection right Determinate if slider after specified amount of time should go to next or prev slide
arrows false Determinate if slider should create arrows to navigate
arrowPrev / arrowNext - Allows to create arrows with custom html. Attr to handle next/prev action will be added automatically. It's necessary to set "arrows" option to true.
animationChange transform Allows to define animation of changing slide
animationChange transform Allows to define animation of changing slide
animationChange transform Allows to define animation of changing slide
generateNav false Determinate if slider should look for navContainer to generate nav
navContainer -- Html element in which slider will look for elements with jedli-target attributes. Value of jedli-target in those elements will determinate index of slider to go To.
filterDelay 0 Set delay before filtering, so you could add custom animation of change or anything
responsive - Set new options to work from specified breakpoint