Skip to content

Releases: tannerhodges/snap-slider

🔥 Fix iOS 15 Scroll Jank

27 Oct 01:19
0d214a0
Compare
Choose a tag to compare

Fixed

iOS 15 Safari's new address-bar-at-the-bottom triggers resize events way more often than previous versions, causing Snap Slider's update function to blow up any scroll that isn't perfectly horizontal (i.e., all scrolls).

This PR hotfixes the issue by replacing our window resize event handler with a ResizeObserver (in all major browsers—but not Internet Explorer, which gracefully ignores updates).

Now, instead of force-updating slider positions on every window resize event, we only update sliders when their container resizes (much better!).

For more details, see #22.

📺 Click here for before/after screencasts…

Before

2021-10-26.Snap.Slider.iOS.15.scroll.jank.mp4

After

2021-10-26.Snap.Slider.iOS.15.scroll.jank.fixed.mp4

🥨 Snap Slider v2

10 Aug 16:57
Compare
Choose a tag to compare

Snap Slider v2 is a full rewrite, packed with new features, improvements, and a few breaking changes.

🆕 Major Features

  • ⚡️ Auto-init data-snap-slider elements on DOM ready.
  • 🗺 Easily add nav elements anywhere in the document with a robust HTML API.
  • 📺 Simple responsive support—just use CSS!
  • ♿️ Keyboard accessibility.
  • ↕️ Vertical slider support (and more!).
  • ⚙️ jQuery support.
  • 🐛 Debug sliders with SnapSlider.debug().

Other Improvements

  • Multiple Builds: Choose whether you want to load the full, lite, or minified versions of the plugin: snap-slider.js, snap-slider.min.js, snap-slider.lite.js, snap-slider.lite.min.js.
  • New Event Callbacks: load, change, change.click, change.scroll, change.keydown, change.focusin, scroll, scroll.start, scroll.end.
  • New Instance Methods: getSlide(), getCurrentSlide(), goto(), addNav(), addGotoButtons(), update(), reset(), destroy(), on().
  • New Static Methods: SnapSlider.get(), SnapSlider.debug().
  • New DOM Property: Easily access the SnapSlider instance for any slider from the DOM via element.SnapSlider.

For more details on the new APIs, check out the readme.

📝 Upgrading to 2.0.0 from v1.x

If you're already using an older version of Snap Slider, here are some notes and examples to help you upgrade to the latest version.

  • Convert JSON → Separate Attributes: Instead of defining all the slider options, data-snap-slider only defines the slider ID now. Each option has its own data attribute.
  • Remove "off" Option: Instead of defining breakpoints in JavaScript, Snap Slider automatically responds to your CSS now, so turning a slider on/off should be entirely handled by CSS styles.
  • Arrows & Pagination → Nav: Instead of targeting navigation elements from the slider, nav elements should target sliders using the data-snap-slider-nav attribute now. For example, remove "pagination": ".example-pagination button" from the slider and add data-snap-slider-nav=".example-slider" to the pagination element instead.
  • Initial → Start: We renamed the initial option to start, and moved its HTML from the JSON config to the data-snap-slider-start attribute instead.
  • Default Start = 1: Instead of defaulting to the middle slide, we default to slide 1 now. If needed, add data-snap-slider-start="middle" to any sliders that should still start in the middle.
  • 0-index → 1-index: Now the current slide index starts at 1 instead of 0, so if you want to goto the first slide you'd say slider.goto(1) instead of slider.goto(0).
  • New "goto" Function: We renamed the goTo method to all lowercase, goto(). We also changed the second parameter immediately to an object options. For example, goTo(1, true) becomes goto(2, { immediate: true }).
  • Items → Slides: We renamed the items option to slides, and moved its HTML from the JSON config to the data-snap-slider-slides attribute.
  • Auto-Initialize on DOM Ready: Instead of requiring extra JS to initialize sliders, Snap Slider v2 automatically inits any sliders with the data-snap-slider attribute on page load. If you're manually loading sliders that already have data-snap-slider attributes, consider removing those extra new SnapSlider() scripts.

Example Diff

- <div class="slider demo-basic" data-snap-slider='{
-   "off": "(min-width: 40em)",
-   "pagination": ".demo-1-pagination button"
- }'>
+ <div class="slider demo-basic" data-snap-slider="demo-1">
    <section class="slider__item card">...</section>
    <section class="slider__item card">...</section>
    <section class="slider__item card">...</section>
  </div><!-- /.slider -->

- <div class="slider-pagination demo-pagination demo-1-pagination">
+ <div class="slider-pagination demo-pagination demo-1-pagination"
+   data-snap-slider-nav="demo-1">
    <button type="button">1</button>
    <button class="is-current" type="button">2</button>
    <button type="button">2</button>
  </div><!-- /.slider-pagination -->
-
- <script>
-   // Query Selector All (returns NodeList as Array)
-   var qsa = function qsa(selector, context) {
-     context = context || document;
-     return Array.prototype.slice.call(context.querySelectorAll(selector));
-   };
-
-   // Init all sliders on page load
-   qsa('[data-snap-slider]').forEach(function (el) {
-     new SnapSlider(el);
-   });
- </script>

Other Changes

  • Removed Properties: Because they can be replaced with other properties, methods, etc., we've removed some properties from SnapSlider instances: arrows, pagination, and previous.

Troubleshooting

  • Uncaught DOMException: If you run into an error like Failed to execute 'querySelectorAll' on 'Document': '[data-snap-slider="{}"]', you probably haven't converted your JSON config to separate attributes yet. Double check your data-snap-slider attributes and make sure they're simple strings (not JSON).

Comparison Table

v1 v2
data-snap-slider='{}' data-snap-slider="slider-id"
Option: initial start / data-snap-slider-start=""
Option: items slides / data-snap-slider-slides=""
Index: 0 Index: 1
Default slide: middle Default slide: 1
Option: off (removed)
Option: arrows data-snap-slider-nav
Option: pagination data-snap-slider-nav
slider.arrows (removed)
slider.pagination (removed)
slider.previous (removed)
slider.currentItem slider.getCurrentSlide()
slider.goTo(1, true) slider.goto(1, { immediate: true })