# tiny-slider 2.0

Tiny slider for all purposes, inspired by Owl Carousel.
Demos
Tests (Can be tested on Firefox 12+, Chrome 15+, Safari 5.1+, Opera 12.1+, IE9+)
Note: some features may need a manual test.

Previous versions: v1, v0

## Contents

+ What's new
+ Features
+ Install
+ Usage
+ Options
+ Responsive options
+ Methods
+ Custom Events
+ Fallback
+ Browser Support
+ Support
+ License

## What's new

- Using `%` instead of `px` (No more recalculation of each slide width on window resize)
- Using CSS Mediaqueries if supported
- Save browser capbility values to localStorage, so they will not be recheck again until browser get upgraded or user clear the localStorage manuelly.
- More options available for `responsive`. (Start from v2.1.0, issue 53)
- Insert `controls` and `nav` before slider instead of after (issue 4)
- Move `autoplay` button out of `nav` container. (Start from v2.1.0)
- Some selector changes in `tiny-slider.scss`

Migrating to v2

- Update `controls` and / or `nav` styles based on their position changes.
- Update the `slider selectors` accordingly if used in your CSS or JS.
- Update styles related to `autoplay` button.

top↑

## Features

- carousel / gallery
- responsive
- fixed width
- auto width (v2.8.1+)
- vertical slider
- gutter
- edge padding (center)
- loop
- rewind (pull 10)
- slide by
- customize controls / nav
- lazyload
- autoplay
- auto height
- touch support
- mouse drag (pull 32)
- arrow keys
- accessibility for people using keyboard navigation or screen readers (issue 4)
- response to visibility changing (pull 19)
- custom events
- nested slider

top↑

## Install

`bower install tiny-slider` or `npm install tiny-slider`

## Usage

#### 1. Add CSS (and IE8 polyfills if needed)

    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/tiny-slider/2.8.1/tiny-slider.css">
    <!--[if (lt IE 9)]><script src="https://cdnjs.cloudflare.com/ajax/libs/tiny-slider/2.8.1/min/tiny-slider.helper.ie8.js"></script><![endif]-->

#### 2. Add markup

    <div class="my-slider">
      <div></div>
      <div></div>
      <div></div>
    </div>
    <!-- or ul.my-slider > li -->

#### 3. Call tns()

Add tiny-slider.js to your page:

    <script src="https://cdnjs.cloudflare.com/ajax/libs/tiny-slider/2.8.1/min/tiny-slider.js"></script>
    <!-- NOTE: prior to v2.2.1 tiny-slider.js need to be in <body> -->

Or import `tns` via `webpack` or `rollup`:

    // yourScript.js
    import { tns } from "./node_modules/tiny-slider/src/tiny-slider"

Or you can even directly import `tns` start from v2.8.3

    <script type="module">
      import {tns} from './src/tiny-slider.js';

      var slider = tns({
        container: '.my-slider',
        items: 3,
        slideBy: 'page',
        autoplay: true
      });
      </script>

top↑

## Options

Option | Type | Description
--- | --- | ---
`container` | Node | String | Default: `'.slider'`. The slider container element or selector.
`mode` | "carousel" | "gallery" | Default: "carousel". Controls animation behaviour. With `carousel` everything slides to the side, while `gallery` uses fade animations and changes all slides at once.
`axis` | "horizontal" | "vertical" | Default: "horizontal". The axis of the slider.
`items` | positive number | Default: 1. Number of slides being displayed in the viewport. If slides less than `items`, the slider won't be initialized.
`gutter` | positive integer | Default: 0. Space between slides (in "px").
`edgePadding` | positive integer | Default: 0. Space on the outside (in "px").
`fixedWidth` | positive integer | false | Default: false. Controls `width` attribute of the slides.
`autoWidth` | Boolean | Default: false. If `true`, the width of each slide will be its natural width as a `inline-block` box.
`viewportMax` (previously `fixedWidthViewportWidth`) | positive integer | false | Default: false. Maximum viewport width for `fixedWidth`/`autoWidth`.
`slideBy` | positive number | "page" | Default: 1. Number of slides going on one "click".
`controls` | Boolean | Default: true. Controls the display and functionalities of `controls` components (prev/next buttons). If `true`, display the `controls` and add all functionalities.
`controlsText` | (Text | Markup) Array | Default: ["prev", "next"]. Text or markup in the prev/next buttons.
`controlsContainer` | Node | String | false | Default: false. The container element/selector around the prev/next buttons. `controlsContainer` must have at least 2 child elements.
`prevButton` | Node | String | false | Default: false. Customized previous buttons. This option will be ignored if `controlsContainer` is a Node element or a CSS selector.
`nextButton` | Node | String | false | Default: false. Customized next buttons. This option will be ignored if `controlsContainer` is a Node element or a CSS selector.
`nav` | Boolean | Default: true. Controls the display and functionalities of `nav` components (dots). If `true`, display the `nav` and add all functionalities.
`navContainer` | Node | String | false | Default: false. The container element/selector around the dots. `navContainer` must have at least same number of children as the slides.
`navAsThumbnails` | Boolean | Default: false. Indecate if the dots are thurbnails. If `true`, they will always be visible even when more than 1 slides displayed in the viewport.
`arrowKeys` | Boolean | Default: false. Allows using arrow keys to switch slides.
`speed` | positive integer | Default: 300. Speed of the slide animation (in "ms").
`autoplay` | Boolean | Default: false. Toggles the automatic change of slides.
`autoplayTimeout` | positive integer | Default: 5000. Time between 2 `autoplay` slides change (in "ms").
`autoplayDirection` | "forward" | "backward" | Default: "forward". Direction of slide movement (ascending/descending the slide index).
`autoplayText` | Array (Text | Markup) | Default: ["start", "stop"]. Text or markup in the autoplay start/stop button.
`autoplayHoverPause` | Boolean | Default: false. Stops sliding on mouseover.
`autoplayButton` | Node | String | false | Default: false. The customized autoplay start/stop button or selector.
`autoplayButtonOutput` | Boolean | Default: true. Output `autoplayButton` markup when `autoplay` is true but a customized `autoplayButton` is not provided.
`autoplayResetOnVisibility` | Boolean | Default: true. Pauses the sliding when the page is invisiable and resumes it when the page become visiable again. (Page Visibility API)
`animateIn` | String | Default: "tns-fadeIn". Name of intro animation `class`.
`animateOut` | String | Default: "tns-fadeOut". Name of outro animation `class`.
`animateNormal` | String | Default: "tns-normal". Name of default animation `class`.
`animateDelay` | positive integer | false | Default: false. Time between each `gallery` animation (in "ms").
`loop` | Boolean | Default: true. Moves throughout all the slides seamlessly.
`rewind` | Boolean | Default: false. Moves to the opposite edge when reaching the first or last slide.
`autoHeight` | Boolean | Default: false. Height of slider container changes according to each slide's height.
`responsive` | Map: { breakpoint: { key: value } } | false | Default: false. Breakpoint: Integer. Defines options for different viewport widths (see Responsive Options).
`lazyload` | Boolean | Default: false. Enables lazyloading images that are currently not viewed, thus saving bandwidth (see demo). NOTE: `width` attribute for each `<img>` is required for `autoWidth` slider.
`touch` | Boolean | Default: true. Activates input detection for touch devices.
`mouseDrag` | Boolean | Default: false. Changing slides by dragging them.
`swipeAngle` | positive integer | Boolean | Default: 15. Swipe or drag will not be triggered if the angle is not inside the range when set.
`nested` | "inner" | "outer" | false | Default: false. Difine the relationship between nested sliders. (see demo) Make sure you run the inner slider first, otherwise the height of the inner slider container will be wrong.
`freezable` | Boolean | Default: true. Indicate whether the slider will be frozen (`controls`, `nav`, `autoplay` and other functions will stop work) when all slides can be displayed in one page.
`disable` | Boolean | Default: false. Disable slider.
`startIndex` | positive integer | Default: 0. The initial `index` of the slider.
`onInit` | Function | false | Default: false. Callback to be run on initialization.
`useLocalStorage` | Boolean | Default: true. Save browser capability variables to localStorage and without detecting them everytime the slider runs if set to `true`.

NOTE:
Prior to v2.0.2, options "container", "controlsContainer", "navContainer" and "autoplayButton" still need to be DOM elements.
E.g. container: document.querySelector('.my-slider')

top↑

## Responsive options

The following options can be redefined in `responsive` field:
`startIndex`,
`items`,
`slideBy`,
`speed`,
`autoHeight`,
`fixedWidth`,
`edgePadding`,
`gutter`,
`controls`,
`controlsText`,
`nav`,
`autoplay`,
`autoplayHoverPause`,
`autoplayResetOnVisibility`,
`autoplayText`,
`autoplayTimeout`,
`touch`,
`mouseDrag`,
`arrowKeys`,
`disable`

    <script>
      var slider = tns({
        container: '.my-slider',
        items: 1,
        responsive: {
          640: {
            edgePadding: 20,
            gutter: 20,
            items: 2
          },
          700: {
            gutter: 30
          },
          900: {
            items: 3
          }
        }
      });
    </script>

NOTE: `fixedWidth` can only be changed to other positive integers. It can't be changed to negtive integer, 0 or other data type. top↑

## Methods

The slider returns a slider object with some properties and methods once it's initialized:

    {
      getInfo: info(),
      events: events, // Object
      goTo: goTo(),
      play: play(),
      pause: pause(),
      isOn: isOn, // Boolean
      rebuild: rebuild(),
      destroy: destroy()
    }

To get the slider information, you can either use the `getInfo()` method or subscribe to an Event. Both return an Object:

    {
                    container: container, // slider container
                   slideItems: slideItems, // slides list
                 navContainer: navContainer, // nav container
                     navItems: navItems, // dots list
            controlsContainer: controlsContainer, // controls container
                  hasControls: hasControls, // indicate if controls exist
                   prevButton: prevButton, // previous button
                   nextButton: nextButton, // next button
                        items: items, // items on a page
                      slideBy: slideBy // items slide by
                   cloneCount: cloneCount, // cloned slide count
                   slideCount: slideCount, // original slide count
                slideCountNew: slideCountNew, // total slide count after initialization
                        index: index, // current index
                  indexCached: indexCached, // previous index
                   navCurrent: navCurrent, // current dot index
             navCurrentCached: navCurrentCached, // previous dot index
            visibleNavIndexes: visibleNavIndexes, // visible nav indexes
      visibleNavIndexesCached: visibleNavIndexesCached,
                        sheet: sheet,
                        event: e || {}, // event object if available
    };

#### getInfo

Get slider information.

    slider.getInfo();

    document.querySelector('.next-button').onclick = function () {
      // get slider info
      var info = slider.getInfo(),
          indexPrev = info.indexCached,
          indexCurrent = info.index;

      // update style based on index
      info.slideItems[indexPrev].classList.remove('active');
      info.slideItems[indexCurrent].classList.add('active');
    };

#### goTo

Go to specific slide by number or keywords.
(NOTE: the number in `goTo()` was 1 based)

    slider.goTo(3);
    slider.goTo('prev');
    slider.goTo('next');
    slider.goTo('first');
    slider.goTo('last');

    document.querySelector('.goto-button').onclick = function () {
      slider.goTo(3);
    };

#### play

Programmatically start slider autoplay when `autoplay: true`.

    slider.play();

#### pause

Programmatically stop slider autoplay when `autoplay: true`.

    slider.pause();

#### destroy

Destroy the slider.

    slider.destroy();

#### rebuild

Rebuild the slider after destroy.

    slider = slider.rebuild();
    // this method returns a new slider Object with the same options with the original slider

## Custom Events

Available events include: `indexChanged`, `transitionStart`, `transitionEnd`, `touchStart`, `touchMove`, `touchEnd`, `dragStart`, `dragMove` and `dragEnd`.

    var customizedFunction = function (info) {
      // direct access to info object
      console.log(info.event.type, info.container.id);
    }

    // bind function to event
    slider.events.on('transitionEnd', customizedFunction);

    // remove function binding
    slider.events.off('transitionEnd', customizedFunction);

top↑

#### Fallback

    .no-js .your-slider { overflow-x: auto; }
    .no-js .your-slider > div { float: none; }

## Browser Support

Firefox 8+ ✓
Chrome 15+ ✓ (Should works on Chrome 4-14 as well, but I couldn't test it.)
Safari 4+ ✓
Opera 12.1+ ✓
IE 8+ ✓

## Support

Live tests and Automated Tests
Live tests, Screenshots and Automated Tests
Cdnjs
Images on demo page are from https://unsplash.com/.

## License

This project is available under the MIT license.