This is a simple carousel implemented in normal javascript and sibilant (lisp) javascript.
You can read more about Sibilant here!
| // This is the carousel implemented in idiomatic javascript | |
| // Converts NodeLists to Arrays | |
| function toArray(x) { | |
| return Array.prototype.slice.call(x); | |
| }; | |
| // Returns array of elements that match css query nested to parent | |
| function queryChildren(parent, query) { | |
| return toArray(Element.prototype.querySelectorAll.call(parent, query)); | |
| }; | |
| // Returns array of elements that match css query | |
| function queryAll(query) { | |
| return toArray(document.querySelectorAll(query)); | |
| }; | |
| // Sets the hidden property of elements based on new index | |
| function to(index, children) { | |
| children.forEach((function(x, i) { | |
| x.hidden = i !== index; | |
| })); | |
| }; | |
| // Gets the current index of carousel | |
| function index(children) { | |
| return (Array.prototype.findIndex.call(children, (function(x) { | |
| return !(x.hidden); | |
| })) || 0); | |
| }; | |
| // Moves to next slide in carousel with wrapping | |
| function rotate(children) { | |
| return to(((1 + index(children)) % children.length), children); | |
| }; | |
| // Rotate carousels once every three seconds | |
| queryAll("[data-carousel]").forEach((function(x) { | |
| return window.setInterval(rotate.bind(window, queryChildren(x, "[data-carousel-slide]")), 3000); | |
| })); |
| ; This is the carousel implemented with Sibilant | |
| ; Converts NodeLists to Arrays | |
| (def toArray (x) (Array.prototype.slice.call x)) | |
| ; Returns array of elements that match css query nested to parent | |
| (def queryChildren (parent query) | |
| (toArray (Element.prototype.querySelectorAll.call parent query))) | |
| ; Returns array of elements that match css query | |
| (def queryAll (query) (toArray (document.querySelectorAll query))) | |
| ; Sets the hidden property of elements based on new index | |
| (def to (index children) | |
| (each (x i) children (set x 'hidden (!= i index)))) | |
| ; Gets the current index of carousel | |
| (def index (children) | |
| (or (Array.prototype.findIndex.call | |
| children (lambda (x) (not x.hidden))) 0)) | |
| ; Moves to next slide in carousel with wrapping | |
| (def rotate (children) | |
| (to (mod (+ 1 (index children)) | |
| children.length) | |
| children)) | |
| ; Rotate carousels once every three seconds | |
| (each (x) (queryAll "[data-carousel]") | |
| (window.setInterval | |
| (rotate.bind window (queryChildren x "[data-carousel-slide]")) | |
| 3000)) |
| // This is the carousel compiled to javascript from Sibilant | |
| var toArray = (function toArray$(x) { | |
| /* toArray eval.sibilant:2:0 */ | |
| return Array.prototype.slice.call(x); | |
| }); | |
| var queryChildren = (function queryChildren$(parent, query) { | |
| /* queryChildren eval.sibilant:5:0 */ | |
| return toArray(Element.prototype.querySelectorAll.call(parent, query)); | |
| }); | |
| var queryAll = (function queryAll$(query) { | |
| /* queryAll eval.sibilant:8:0 */ | |
| return toArray(document.querySelectorAll(query)); | |
| }); | |
| var to = (function to$(index, children) { | |
| /* to eval.sibilant:11:0 */ | |
| return children.forEach((function(x, i) { | |
| /* eval.sibilant:11:31 */ | |
| return x.hidden = i !== index; | |
| })); | |
| }); | |
| var index = (function index$(children) { | |
| /* index eval.sibilant:14:0 */ | |
| return (0 || Array.prototype.findIndex.call(children, (function(x) { | |
| /* eval.sibilant:14:89 */ | |
| return !(x.hidden); | |
| }))); | |
| }); | |
| var rotate = (function rotate$(children) { | |
| /* rotate eval.sibilant:17:0 */ | |
| return to(((1 + index(children)) % children.length), children); | |
| }); | |
| queryAll("[data-carousel]").forEach((function(x) { | |
| /* eval.sibilant:20:0 */ | |
| return window.setInterval(rotate.bind(window, queryChildren(x, "[data-carousel-slide]")), 3000); | |
| })); |
| <!doctype html> | |
| <html> | |
| <head> | |
| <title>Sibilant Carousel Demo</title> | |
| <meta charset="utf-8"> | |
| <style> | |
| html, body { height: 100% } | |
| body { | |
| margin: 0; | |
| display: flex; | |
| justify-content: center; | |
| align-items: center; | |
| } | |
| [data-carousel] { | |
| width: 50em; | |
| max-width: 100vw; | |
| height: 40em; | |
| max-height: 100vh; | |
| overflow: hidden; | |
| position: relative; | |
| } | |
| [data-carousel-slide] { | |
| position: absolute; | |
| top: 0; | |
| left: 0; | |
| margin: 0; | |
| width: 100%; | |
| height: 100%; | |
| overflow: hidden; | |
| border-radius: 1em; | |
| transition: visibility 2s, opacity 2s; | |
| } | |
| /* allow transition to fade between items */ | |
| [data-carousel-slide][hidden] { | |
| display: block !important; | |
| opacity: 0; | |
| } | |
| /* make img behave like background-size: cover */ | |
| [data-carousel-slide] img { | |
| position: absolute; | |
| min-width: 100%; | |
| min-height: 100%; | |
| width: 100%; | |
| height: auto; | |
| } | |
| [data-carousel-slide] figcaption { | |
| box-sizing: border-box; | |
| position: absolute; | |
| width: 100%; | |
| height: 100%; | |
| font-size: 5em; | |
| padding: 1em; | |
| color: white; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <section data-carousel> | |
| <figure data-carousel-slide> | |
| <img src="https://upload.wikimedia.org/wikipedia/commons/5/50/A_beautiful_stray_cat.jpg"> | |
| <figcaption>Lorem ipsum</figcaption> | |
| </figure> | |
| <figure hidden data-carousel-slide> | |
| <img src="https://upload.wikimedia.org/wikipedia/commons/1/1a/Be_togeather.jpg"> | |
| <figcaption>dolor sit amet</figcaption> | |
| </figure> | |
| <figure hidden data-carousel-slide> | |
| <img src="https://upload.wikimedia.org/wikipedia/commons/e/ef/Cats_-_Kediler_04.jpg"> | |
| <figcaption>consectetur adipiscing elit</figcaption> | |
| </figure> | |
| </nav> | |
| <script src="./carousel.js"></script> | |
| </body> | |
| </html> |