Giter Club home page Giter Club logo

snap-slider's Introduction

πŸ₯¨ Snap Slider

Simple JavaScript plugin to manage sliders using CSS Scroll Snap.

⚑️ Quick Start

  1. npm install @tannerhodges/snap-slider
  2. import SnapSlider from '@tannerhodges/snap-slider'; -- OR -- <script async src="snap-slider.min.js"></script>
  3. Add data-snap-slider to your elements.

πŸ“– Outline

πŸ€” Why?

CSS Scroll Snap makes sliders as simple as a few lines of CSS, but you still need JavaScript for things like buttons and event handlers.

Snap Slider makes that as easy as adding a data-snap-slider attribute.

πŸ‘‰ For a full explanation & demos, check out the docs.

βš™οΈ Install

  1. Install the package.
npm install @tannerhodges/snap-slider
  1. Import the package into your application script.
import SnapSlider from '@tannerhodges/snap-slider';

Or, if you prefer, include the script in your HTML.

<script async src="snap-slider.min.js"></script>
  1. Add data attributes to your CSS sliders.
<ul class="slider" data-snap-slider="example">
  <li class="slide">...</li>
  <li class="slide">...</li>
  <li class="slide">...</li>
  <li class="slide">...</li>
</ul>

<ul class="slider-nav" data-snap-slider-nav="example">
  <li><button type="button">Previous</button></li>
  <li><button type="button">1</button></li>
  <li><button type="button">2</button></li>
  <li><button type="button">3</button></li>
  <li><button type="button">4</button></li>
  <li><button type="button">Next</button></li>
</ul>

πŸ‘¨β€πŸ« HTML API

Elements

  • data-snap-slider="<ID>" - Container. Create a slider for this container element. Should have CSS position: relative, overflow: scroll, and scroll-snap-type defined.
  • data-snap-slider-nav="<ID>" - Nav. Wrap around a group of buttons to specify which slider they control.
  • data-snap-slider-goto="<SLIDE>" - "Goto" Button. Tell a button which slide it should go to. (Can target specific sliders using <ID>:<SLIDE> syntax.)
    • Possible values: Numbers (starting at 1), first, middle, last, prev, next.

Options

  • data-snap-slider-slides - By default, Snap Slider assumes all the container's children are slides. If you have non-slide elements in your slider, add this attribute to the container to specify which elements should be treated as slides.
  • data-snap-slider-align="<ALIGN>" - Snap Slider checks each slide's CSS scroll-snap-align to calculate its scroll position, but older browsers fail to return this value. If you need to support center or end alignments in Internet Explorer, add this attribute to a container or slide to specify its alignment.
    • Possible values: start, end, or center.
  • data-snap-slider-start="<SLIDE>" - Sliders start on slide 1 by default. Add this attribute to a container to specify a different slide to start on.
    • Possible values: Numbers (starting at 1), first, middle, last.
  • data-snap-slider-loop="<BOOLEAN>" - Previous/next buttons are disabled on the first/last slides by default. Add this attribute to a container to enable them to loop around to the other end of the slider (e.g., clicking a previous button on slide 1 will goto the last slide).
  • data-snap-slider-buttons="<SELECTOR>" - Snap Slider automatically inits buttons in nav elements as goto buttons. Add this attribute to a container or nav to specify which elements should be treated as goto buttons.
  • data-snap-slider-prev="<SELECTOR>" - Snap Slider tries to detect previous buttons based on their content and class names (e.g., if the text or class contains the string "prev"). Add this attribute to a container or nav to target a custom selector for previous buttons.
  • data-snap-slider-next="<SELECTOR>" - Snap Slider tries to detect next buttons based on their content and class names (e.g., if the text or class contains the string "next"). Add this attribute to a container or nav to target a custom selector for next buttons.

πŸ€– JavaScript API

Constructor

const slider = new SnapSlider(
  // `container` - This is the slider's container element.
  // You can pass in a string selector, Element, NodeList, or jQuery object.
  container,

  // `options` - This object extends the default settings.
  {
    // `options.id` - String ID for this slider.
    //   Use this to associate containers, navs, and goto buttons.
    //   If empty, defaults to `container.children`.
    id: '',

    // `options.slides` - String selector to target slide elements.
    //   Useful if you have non-slide elements in your container.
    //   If empty, defaults to `container.children`.
    slides: '',

    // `options.align` - String to specify fallback alignment for older browsers.
    //   Mimics `scroll-snap-align` for browsers that don't support CSS Scroll Snap.
    align: '',

    // `options.nav` - String selector to target nav elements.
    //   Looks for matches across the whole document.
    nav: '',

    // `options.buttons` - String selector to target goto buttons.
    //   Looks for matches in container and nav elements.
    buttons: '',

    // `options.prev` - String selector to target previous buttons.
    //   Looks for matches in container and nav elements.
    prev: '',

    // `options.next` - String selector to target next buttons.
    //   Looks for matches in container and nav elements.
    next: '',

    // `options.start` - Number or string alias to change which slide is current on load.
    //   Accepts any valid goto alias (numbers starting at 1, `first`, `middle`, `last`).
    start: 1,

    // `options.loop` - Boolean to enable prev/next buttons to loop around to the other end of the slider.
    loop: false,

    // `options.on` - Object to add callbacks for different events.
    on: {
      'load': () => {},
      'change': () => {},
      'change.click': () => {},
      'change.scroll': () => {},
      'change.keydown': () => {},
      'change.focusin': () => {},
      'scroll': () => {},
      'scroll.start': () => {},
      'scroll.end': () => {},
    },
  }
);

Properties

  • align - What's this slider's CSS scroll-snap-align?
  • callbacks - Functions to fire for each slider event.
  • container - Container element.
  • current - Index of current slide. Values start at 1.
  • id - Slider ID.
  • loop - Boolean. Should slide loop or not?
  • options - Slider options (default values + custom overrides).
  • scrolling - Boolean. Is the slider scrolling at this moment?
  • slides - Array of slides.
  • transition - Object. Are we in the middle of a transition? Where from, to, etc.?

Instance Methods

  • getSlide(index) - Get a specific slide element. Accepts any valid goto alias.
  • getCurrentSlide() - Get the current slide element.
  • goto(index, [options]) - Go to a slide.
    • Goto Aliases - Numbers (starting at 1), first, middle, last, prev, next.
    • options.focus - By default, we focus slides when you go to them (except for relative changes like prev and next). Use this option to disable the default focus handling.
    • options.force - Force-update the scroll position, even if we're already on the current slide.
    • options.ignoreCallbacks - Ignore custom callbacks for events.
    • options.immediate - Immediately update position without smooth scrolling.
  • addNav(containerOrOptions, [options]) - Add a nav element for the current slider. Automatically hooks up any nav buttons inside the nav.
    • options.container - The nav element. Defaults to containerOrOptions. Limits the query for buttons, prev, and next to be inside the nav container (instead of the whole document).
    • options.buttons - String selector to target goto buttons inside the nav container. If empty, defaults to button.
    • options.prev - String selector to target previous buttons inside the nav container.
    • options.next - String selector to target next buttons inside the nav container.
  • addGotoButtons(buttonsOrOptions, [options]) - Add goto buttons for the current slider.
    • options.container - A parent nav element. If set, limits the query for buttons, prev, and next to be inside the nav container (instead of the whole document).
    • options.buttons - String selector to target goto buttons. Defaults to buttonsOrOptions.
    • options.prev - String selector to target previous buttons.
    • options.next - String selector to target next buttons.
  • update() - Update this slider (e.g., on resize). Basically just repositions the current slide.
  • reset() - Reset this slider (e.g., after adding or removing a slide). Updates the slide elements, our internal slides array, and repositions the current slide.
  • destroy() - Destroy this slider. Stop any active transitions, remove its event listeners, and delete it from our internal array of slider instances.
  • on(event, callback) - Add callbacks to fire on specific events.
    • change - Fires any time the current slide changes.
    • change.click - Fires when a user clicks a goto button.
    • change.scroll - Fires when a user scrolls to another slide.
    • change.keydown - Fires when a user is focused inside the container and presses an arrow key to change the current slide (e.g., up, down, left, or right).
    • change.focusin - Fires when a slide gains focus.
      • Note: For keyboard accessibility, we automatically focus the target slide whenever a user clicks a non-relative goto button. In other words, if you goto any index besides prev or next we'll auto-focus that slide.

Static Methods

  • SnapSlider.get(id) - Get the SnapSlider object for a slider based on its ID.
  • SnapSlider.debug([idOrElements]) - console.log info about a slider, its nav, or goto buttons.

HTML Properties

  • Element.SnapSlider - After a slider is intialized, you can access its SnapSlider instance by getting the element's SnapSlider property. For example, document.querySelector('.example').SnapSlider.

Example

import SnapSlider from '@tannerhodges/snap-slider';

// Create a new slider.
const slider = new SnapSlider('.example', {
  id: 'example-slider',
  nav: '.example-nav',
  start: 'middle',
});

// The rest is up to you!
// πŸƒβ€β™‚οΈ Go make something!

✍️ CodePen Examples

TODO: Examples

πŸ“ Changelog

snap-slider's People

Contributors

tannerhodges avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

snap-slider's Issues

Safari Bug: goto({ focus: false }) still triggers focus on scroll.end event

Issue was reported where trying to call slider.goto({ focus: false }) ended up still focusing the slide in Safari.

Seems like the scroll.end event is somehow delayed in Safari, and since it doesn't inherit options from the initial goto() call it focuses by default.

In this specific example, it was for two synced sliders (via a change callback). Couple different ways we could go (e.g., making "sync" a core feature, or adding a "disable focus" option, etc.).

Going to have to dig into this one (and hope Cypress implements Safari support soon 😬).

Improve UX when multiple slides are visible at the same time

Feature Request:

It would be great if we could improve the UX when there are multiple slides visible at the same time. For reference, check out the Basic Example. There you will see that when you click to show the 3rd slide, it displays the 3rd and 4th images as expected. At this point, it would be great if the next button is disabled and buttons 3 and 4 show as β€œcurrent”. Below is a quick illustration of what I'm referring to.

snap-slider-feature-request-navigation-active-states

swipe on mobile devices

Normally on mobile (or even desktop), we can touch and swipe the slide but with snap slider if we hide the scrollbar then look like we can't touch to scroll anymore.
Maybe it is something we need to implement with Javascript? It would be great because in fact, we always have to hide the scrollbar while we still need the touch functionality @tannerhodges

Disabling 'Peek' slides.

Hi Tanner,

I am using your plugin to create some awesome sliders. When using them for a product slider, with 12 products in total and only 4,5 of them in the viewport, clicking on one of the products inside the viewport causes the slider to move to the clicked product, instead of just going to the page as told in the tag.

Removing the dot and arrow navigation had no result.

Is there some way to disable that when a user clicks a slide the slider actually moves? It should only move by scrolling or using the navigation elements.

Thanks in advance,
Koen

Below is my code with Tailwind and Twig:

PRODUCT CARD DATA
PRODUCT CARD DATA
PRODUCT CARD DATA
PRODUCT CARD DATA
PRODUCT CARD DATA
PRODUCT CARD DATA
PRODUCT CARD DATA
PRODUCT CARD DATA
PRODUCT CARD DATA
PRODUCT CARD DATA
PRODUCT CARD DATA
<ul class="snap-slider-nav snap-slider-nav-dots mt-4" data-snap-slider-nav="ladies">
	<li>
		<button type="button" class="snap-slider-nav-button is-current" data-snap-slider-goto="1">1</button>
	</li>
	<li>
		<button type="button" class="snap-slider-nav-button" data-snap-slider-goto="2">2</button>
	</li>
	<li>
		<button type="button" class="snap-slider-nav-button" data-snap-slider-goto="3">3</button>
	</li>
	<li>
		<button type="button" class="snap-slider-nav-button" data-snap-slider-goto="4">4</button>
	</li>
	<li>
		<button type="button" class="snap-slider-nav-button" data-snap-slider-goto="5">5</button>
	</li>
	<li>
		<button type="button" class="snap-slider-nav-button" data-snap-slider-goto="6">6</button>
	</li>
	<li>
		<button type="button" class="snap-slider-nav-button" data-snap-slider-goto="7">7</button>
	</li>
	<li>
		<button type="button" class="snap-slider-nav-button" data-snap-slider-goto="8">8</button>
	</li>
	<li>
		<button type="button" class="snap-slider-nav-button" data-snap-slider-goto="9">9</button>
	</li>
	<li>
		<button type="button" class="snap-slider-nav-button" data-snap-slider-goto="10">10</button>
	</li>
	<li>
		<button type="button" class="snap-slider-nav-button" data-snap-slider-goto="11">11</button>
	</li>
</ul>

<ul class="snap-slider-nav snap-slider-nav-arrows mt-4" data-snap-slider-nav="ladies">
	<li>
		<button type="button" data-snap-slider-goto="prev" class="snap-slider-arrow snap-slider-nav-prev is-disabled">
			ARROW
		</button>
	</li>
	<li>
		<button type="button" data-snap-slider-goto="next" class="snap-slider-arrow snap-slider-nav-next">
			ARROW
		</button>
	</li>
</ul>

This generates the following section
Schermafbeelding 2022-03-04 om 14 03 04

Best practice for performance

For autoplay implementation, I think we should use requestanimationframe (and requestidlecallback) instead of using interval which block the browser paint.

next prev still working?

Hello, great plugin!

Question, should

data-snap-slider-prev="<SELECTOR>"

go into data-snap-slider-nav ?
Maybe this could more clearly in the documentation

Otherwise, it's not working
But

 :data-snap-slider-goto="`${data.__typename}:prev`"

is working

Disable changing slide on slide click

Is there a way to disable the functionality of changing the slide when the slide is clicked, so, for instance, a user can click on the slide to select text or click on a link?

performance measurement

The most important nowadays is performance. Do you have a comparison with other popular sliders like owl,...etc to see if a slider based on Snap scroll is better than other ones?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.