rcbyr / keen-slider Goto Github PK
View Code? Open in Web Editor NEWThe HTML touch slider carousel with the most native feeling you will get.
Home Page: https://keen-slider.io/
License: MIT License
The HTML touch slider carousel with the most native feeling you will get.
Home Page: https://keen-slider.io/
License: MIT License
And when will the autoplay solution be on vanilla js? :)
Hi!
If the site has a preloader and at the beginning of the page loading there is no scrollbar, then "keen-slider__slide" has a width excluding the width of the scrollbar
So I'm using React v16.3.1 and Typescript.
const [sliderRef] = useKeenSlider();
...
<div ref={sliderRef}>
<img src={imageUrl} alt="some" />
<img src={imageUrl} alt="some" />
<img src={imageUrl} alt="some" />
</div>
And basically it has the red underline on the ref
prop of the div saying
Type 'RefObject<HTMLElement>' is not assignable to type 'string | ((instance: HTMLDivElement | null)
When using loop = true
, and reaching the last (or the first) slide, the arrow change it's style because the .arrow--disabled
class is set.
We shouldn't change arrow style when loop = true
since none of them should be disabled
First of all, You're the best! Thank You!
Second... When you have slidesPerView set as the same number of slides (On my case, 7), the plugin doesn't show the 7th slide.
Here my code: https://codesandbox.io/s/keen-slider-spacing-angular-i1w7d?file=/src/app/app.component.ts
On ngOnInit function, i set the variable "this.slides" with an array of 7 objects.
In app.component.html i used a *ngFor to render the divs and then... the 7th slide don't show up on start.
Would you happen to have a blog post or resource about how you implemented native-like sliding?
I'm working on an application where I want users to slide to flip flash cards so your package stood out to me in this week's issue of JS Weekly. Next time I need a carousel I'll be sure to give this package a try ๐
Hi!
So I had been trying to override the slideChanged()
method using the refresh()
method, as mentioned in the documentation, the refresh
method will accept an object that will initialize the slider and override with the method passed in the options object:
Original
slideChanged: s => {
state = s.details().relativeSlide;
}
Using a button onclick function to call the refresh:
function move_to_slide(n) {
slider.refresh({
slideChanged: s => {
state = s.details().relativeSlide;
console.log("Slide change");
}
});
slider.moveToSlideRelative(n);
}
Expected output:
It will console log "Slide change" when after I click the button and interact with the slider
Actual output:
No log is output in the console.
Very much thanks for helping!
I try to add multiple keen-slider on one page with dots using vanilla.js. Some sliders may have 3 dots, some have 4.
When I change slider, the event "slideChanged" will pass "instance" value. But I can't map to the slider that using it. Then I can't add active class to proper ".dot" element.
Do you have any suggestion if I'd like to use multiple sliders? Or how can I get DOM / ID from instance.details() ?
Thank you very much for your time and your great slider :)
Hi,
Please add an option to remove mouse events to drag slides, allowing only touch events.
While testing it, I realised that the autoplay feature is missing.
Are we going to see this implemented soon ?
Autoplay with the control of duration and an onHoverStop event would be a nice addition
The Problem
When trying to force overflow: visible;
on .keen-slider
and setting loop: true
on the slider instance, slides appear and disappear as the slider jumps between the start/end transforms.
Possible Solution
I'm sure you've sen how other libs get around this by cloning the start/end elements, maybe could be done if loop: true
is set. Glide also has a really nice peek
option, allowing elements just outside the bounds of the slider to be pulled in.
Also, thanks for creating this โ all of the slider libraries I've tried over the past few years are either extremely large (swiper.js), or have average to horrible touch behaviour (glide.js and many others). You have nailed both of these, so well done!
Have you given through to making this accessible?
https://www.w3.org/WAI/tutorials/carousels/
nice to haves:
keyboard navigation between slides
move focus into first slide after transition
convert to UL / LI elements
announce transitions via aria-=live
accessible example: https://www.w3.org/WAI/tutorials/carousels/full-code/
Seems like some of this could be implemented by devs implementing your slider - but it would be nice if it was handled upstream
It would be really useful if the slider included a mode where the most you can move per swipe is one slide forward or back. Right now when mode is set to "snap" and I swipe faster the slider usually stops after two slides.
I saw your post on Reddit and was very 'keen' on using this! :) I initialized the container on ngAfterViewInit and then make an API call. The data from the API call render in an ngFor loop in the HTML within the slider. I don't see it rendering. Am I missing something here?
I'm using Angular 9 btw.
It would be nice if the slider supports RTL.
Hi ๐,
I'm Romuald from the Lsos, an organization that develops financial solutions for open source, and we are currently reaching out to projects we like.
We have several solutions depending on your financial goals and we can help with:
For example, we can increase donations with the Lsos Donation Reminder and the Lsos Donation Fund.
We can also leverage a license clause if you are interested in receiving a substantial remuneration from your open source work. Our license clauses are designed to keep code:
Large companies want two things: open source and a way to pay for software. They prefer paying for well-maintained tools rather than using free but unreliable tools. At the end of the day, a license clause can be a win for everyone.
We are focusing on solving the financials of a handful of projects first to then eventually tackle the open source financing problem at large. Let me know if you are interested.
Rom
Thank you for your awesome works
When rendering keen-slider on the server-side; the slide widths & heights are calculated only when JS starting to work -> causing FOUC
The possible solution I think of is exporting sliderSetWidths & friends (https://github.com/rcbyr/keen-slider/blob/master/src/keen-slider.js#L449), so the user can calculate the widths & heights on the server-side before sending it to the client
Hi i'm getting an error in my Gatsby site when trying to use the dot naviation from the example. I'm assuming this is from my lack of experience with react and gatsby. I've copied everything from the example - if anyone could help me, i'd apprecitate it! (Loving keen-slider btw - thank you!)
TypeError: Array(...).keys(...).concat is not a function
Compiled:
Array(slider.details().size).keys().concat().map(function (idx) {
Source:
{slider && (
<div className="dots">
{[...Array(slider.details().size).keys()].map(idx => {
return (
<button
key={idx}
onClick={() => {
slider.moveToSlideRelative(idx);
}}
className={"dot" + (currentSlide === idx ? " active" : "")}
/>
);
})}
</div>
)}
I've created a reproducible example on codesandbox.
Resizing the window makes the slider behave as expected.
This is how I'd use the slider in my app, where the variable containing the image URLs would be null initially and then set after fetching the data from the server. I'd like to understand why this is currently a problem.
Thanks for creating this library.
https://www.w3schools.com/tags/att_input_min.asp
As the link above, I want to set the min max value and move it to the set value when the value is over.
How can it be implemented?
As a Vue developer I would like to use directive based syntax that is similar to React Hooks:
import React from 'react'
import 'keen-slider/keen-slider.min.css'
import { useKeenSlider } from 'keen-slider/react'
export default () => {
const [sliderRef, slider] = useKeenSlider()
return (<div ref={sliderRef}>
<div class="keen-slider__slide">1</div>
<div class="keen-slider__slide">2</div>
<div class="keen-slider__slide">3</div>
</div>)
}
Proposed Vue syntax:
<template>
<div
class="keen-slider"
v-slider:mySlider="sliderOptions"
...
</div>
</template>
import 'keen-slider/keen-slider.min.css'
import { useKeenSlider } from 'keen-slider/vue'
const {directive} = useKeenSlider()
export default {
name: 'MySlider',
directives: {
slider: directive
},
data() {
return {
sliderOptions: {...}
}
}
}
Such syntax will allow much cleaner slider instantiation with no need to do anything in mounted hook as well as no need to manually destroy slider instance since that can be done internally by watching directive detachment from the DOM
Hi @rcbyr
Thanks for this cool slider and lightweight โค๏ธ
dir="rtl"
attribute for element or an option in KeenSlider
like your Sandbox Example ZoomOut animation which that really dope if we can register our animation like swiper.js
https://swiperjs.com/api/#coverflow-effect
https://swiperjs.com/api/#flip-effect
https://swiperjs.com/api/#cube-effect
with regards
Just started using keen-slider in my Svelte/Sapper project and I hope it will go well. I plan to replace Siema (keen-slider seems to be even more lightweight?) but getting inspiration and converting existing examples from React to Svelte way is a bit of pain, I guess would be really cool for everyone if there would always be a Vanilla.js example a reference alongside already existing examples? (Not asking for Svelte ones, as this would be too much). Cheers!
If slidesPreView is more than 1, it would be great to be able to tap on a slide to make that one active.
Thanks for the awesome library.
One suggestion here is for the mode
option,
function moveWithSpeed() {
hook('beforeChange')
switch (options.mode) {
case 'free':
moveFree()
break
case 'free-snap':
moveSnapFree()
break
case 'snap':
default:
moveSnapOne()
break
}
}
wondering if we can make it pluggable so only the default one will be built in, and the library could export other mode such as
import { freesnap }, KeenSlider from 'keen-slider';
const slider = new KeenSlider('#my-slider', {
loop: true,
modeFunc: freesnap
});
In this case its easier to tree-shake methods the people are not using it and reduce the overall bundle size.
It might not be totally easy to implement without refactor as most of the function are written accessing global variable, just throwing some idea to make the library more flexible.
Cheers
I realise this is likely not so much an issue as a feature request or cry for help...
My data is a list / array of items, each of which has as one value an array of a varying number of image URLs that I'd like to display in a keen-slider instance. I want to display all my data in a scrollable list.
I created a component that creates an instance of keen-slider from an @input that is an array of URLs (the images to display). All pretty standard stuff. Works fine.
If I use a standard '*ngFor' style list for my data this works a treat, but my data could grow and cause my list to get very long so I tried to use a 'cdk-virtual-scroll-viewport' and a '*cdkVirtualFor' list within that. This breaks my keen-slider implementation though. It seems to be down to the implementation using '*ngFor' internally to create it's 'slides'. Projecting the 'slides' using ng-content has the same issue (only the final 'slide' is present). I though that maybe using the 'slides' option of keen-slider with a function to create the slide elements might be a way forward, but I can't figure out how to write such a function. From the docs:
Function, that return HtmlElement[]
If my 'slides' were a set of fixed elements and didn't have to be created from data then there wouldn't be problem. It just seems that once you try to iterate something to create slides within a component within a '*cdkVirtualFor' list something goes haywire.
I don't know if this is a bug, or a feature request
I've noticed, that the slideChanged event, is slightly delayed, when using a dot-value in slidesPerView โ I've been able yo replicate it, with the following example:
import "./styles.css";
import "keen-slider/keen-slider.min.css";
import KeenSlider from "keen-slider";
const slider = new KeenSlider("#my-keen-slider", {
slidesPerView: 2.5,
slideChanged: (instance) => {
console.log("slideChanged");
}
});
const next = document.querySelector("[data-next]");
next.addEventListener("click", () => slider.next());
Please add before and after offset like slidesOffsetBefore and slidesOffsetAfter like swiper.js. It's necessary when the slider is used full width screen and the slides go over the screen. Like slider on this page - http://exdeniz.protechnolog.danke.agency/career/
when the total slider count is smaller than slidesPerView, the slides width is not parentWidth / slidesPerview
this is the source code
https://codesandbox.io/s/keen-slider-spacing-react-forked-48x2h?fontsize=14&hidenavigation=1&theme=dark
import React from "react";
import { useKeenSlider } from "keen-slider/react";
import "keen-slider/keen-slider.min.css";
import "./styles.css";
export default (props) => {
const [sliderRef] = useKeenSlider({ slidesPerView: 3, spacing: 15 });
const [sliderRef2] = useKeenSlider({ slidesPerView: 3, spacing: 15 });
return (
<>
<div ref={sliderRef} className="keen-slider">
<div className="keen-slider__slide number-slide1">1</div>
<div className="keen-slider__slide number-slide2">2</div>
<div className="keen-slider__slide number-slide3">3</div>
<div className="keen-slider__slide number-slide4">4</div>
<div className="keen-slider__slide number-slide5">5</div>
<div className="keen-slider__slide number-slide6">6</div>
</div>
<div ref={sliderRef2} className="keen-slider">
<div className="keen-slider__slide number-slide1">1</div>
<div className="keen-slider__slide number-slide2">2</div>
</div>
</>
);
};
Is it possible to keep the slider's width the same when the slider count is smaller than slidesPerView?
I'm using React v16.3.1 and Typescript.
dragSpeed: (val, instance) => {
const height = instance.details().widthOrHeight;
return val * (height / ((height / 2) * Math.tan(slideDegree * (Math.PI / 180))) / slidesPerView);
},
I am getting an error about the type (val, instance) => {...
and how do I set the type?
Even if I specify as below, type error occurs.
js(val:number, instance:any) => {...
Hey!
I am trying to implement the slider ("keen-slider": "^4.2.1")
inside a component. This component then renders within a page component that has a <section></section>
. The slide that I am trying to render is material cards with a min-width of 365px;
I want three to show in the center of the page max-width 80% on large screens and two on tablets and only one on mobiles.
Similar to this: codesandbox.
The component renders only 1 card for some reason.
Hi there!
The slider looks brilliant, wonderful job! I'm curious if there are any plans on adding support for vertical sliders/carousels? We'd definitely switch over to your library in my company but vertical support is, unfortunately, a must.
Thanks so much!
Regards!
F.
hi there,
is there a built in way to intercept or distinguish clicks from drags within a slider element?
my slide content is interactive and might probably have even another slider embedded.
problem is that if i click i also receive drag events and vice versa.
or do i need to stop event propagation by using hammerjs to the parent slide container or similar?
thanks for help!
add the use of modern CSS Scroll Snap API. it might bring a better performance.
Also a common behaviour is scrolling with mouse / pad and the slider does not react to these common gestures.
Hi,
First of all thanks for a great slider, I'm really enjoying it.
I ran in to a little bug where the "rubberband" might not pull the slides back if you push it enough.
See attachment.
Thanks
rubberband.mov.zip
Env:
iOS webkit
A mediocre network traffic
Problem:
Found the issue that slide animation lost a lot of frames when page is almost loaded and ui thread is painting some media elements such as img tag or CSS background.
Some info:
Dived into performance debugging and found the requestAnimationFrame was delayed by nothing. But it took 50ms, 100ms or even more time to do next moveAnimateUpdate
detecting by console.log
. The issue could be reproduced in the demo page without page cache in a mediocre network traffic.
I saw your post on reddit and I have to say, I'm really glad I found out about this library! Definitely the best one out there with the most native feeling indeed.
However, I was wondering if it's supported to use the snapping when just scrolling? Like with a trackpad for example. I created a repo where I tried to use css scrollsnapping as well, but this won't work as all "children" are positioned absolute.
Is there a way to achieve this? Or is it not supported, which I could also understand.
Can we have animations (fade/slide) and autoplay functionality build-in instead on depending on external code for vue/angular/react? As it is this functionality is not avaliable for vanillajs at all. In other carousel/slider scripts this is normally passed as arguments like this.
var slider = new KeenSlider('#my-slider', {
loop: true,
animation: 'slide', // or fade
autoplay: 1000, // time in ms
})
The title speaks for itself :)
node-sass@v5
does not watch or properly import CSS, but converts any such calls to import(example.css);
. Whilst Webpack handles this change gracefully, CSS files are not similarly handled when importing directly using node-sass
(using something like Gulp and without any additional plugins).
I see in the src/
for this repo there is a SCSS file - it would be great if this was included as part of the npm
package for import, as well as a CSS file.
The stylesheet can also be converted to actual SCSS too, nesting the selectors and removing the prefixes (which can ultimately be handled by the end user IMO, allowing them to negate any prefixes they don't want/need), turning the SCSS into this (as a quick, untested example):
.keen-slider {
display: block;
overflow: hidden;
position: relative;
user-select: none;
touch-action: pan-y;
-webkit-tap-highlight-color: transparent;
&__slide {
position: absolute;
overflow: hidden;
width: 100%;
min-height: 100%;
}
&--vertical &__slide {
min-height: auto;
}
}
P.S. Thanks for the plugin!
For loop: true
If we have 5 slides and use slider.next()
we move slide 5 > 1.
If we have 5 slides and use slider.moveToSlide(0)
we move slide 5 > 4 > 3 > 2 > 1
It might feel the mostest native if we would slide the shortest route to the next slide.
Use case: A slider with thumbails underneath for navigation
I am unsure whether this is configurable at all, but at present, using keen-slider
impacts our lighthouse scores on a project I'm working on for the following reasons:
https://web.dev/uses-passive-event-listeners/?utm_source=lighthouse&utm_medium=devtools
I've investigated and can see that there are a few places where the event listeners never call preventDefault
, or optionally call preventDefault
based on configuration, and can therefore identify if they are passive
or not.
Without this flag, the browser will wait for events to complete before deciding if it should take over scrolling. With the flag, the browser knows immediately that it can scroll without waiting.
Multiple event listeners in this block can identify that they are passive
event listeners that will not prevent scrolling:
keen-slider/src/keen-slider.js
Lines 161 to 179 in 1af5b7b
dragstart
keen-slider/src/keen-slider.js
Lines 164 to 167 in 1af5b7b
passive
flag when isTouchable()
returns false
eventDragStart
keen-slider/src/keen-slider.js
Lines 80 to 91 in 1af5b7b
preventDefault
, so the following references should use the passive
flag:
keen-slider/src/keen-slider.js
Line 168 in 1af5b7b
keen-slider/src/keen-slider.js
Line 172 in 1af5b7b
eventDragStop
keen-slider/src/keen-slider.js
Lines 93 to 105 in 1af5b7b
preventDefault
, so the following references should use the passive
flag:
keen-slider/src/keen-slider.js
Lines 170 to 171 in 1af5b7b
keen-slider/src/keen-slider.js
Lines 174 to 175 in 1af5b7b
wheel
keen-slider/src/keen-slider.js
Lines 176 to 178 in 1af5b7b
isTouchable()
returns false
:
keen-slider/src/keen-slider.js
Lines 156 to 159 in 1af5b7b
Hey @rcbyr!
I saw your library on reddit and was blown away! I was wondering if you plan on supporting variable widths for slides?
Thanks!
Hi I encounter issue when I need to change the list for rendering the slide, after changing the list, the width of each slide cannot be set correctly.
example:
https://codesandbox.io/s/keen-slider-multiple-react-forked-f8y2i?file=/src/App.js
See console output from this example: https://codesandbox.io/s/keen-slider-hooks-issue-9yneh?file=/src/App.js
When I navigate between slides, slideChanged
will update the state value for currentSlide
with the sliders relative slide.
dragEnd
is called momentarily before slideChanged
, and will output the sliders relative slide, and the state value for currentSlide
However, even when currentSlide
is updated, the internal hook hangs on to the old value as seen in the console output:
****** currentSlide 0
****** currentSlide 0
***** slideChanged - relativeSlide 0 currentSlide 0
****** currentSlide 0
****** currentSlide 0
***** dragEnd - relativeSlide 0 currentSlide 0
***** slideChanged - relativeSlide 1 currentSlide 0
****** currentSlide 1
****** currentSlide 1
***** slideChanged - relativeSlide 2 currentSlide 0
****** currentSlide 2
****** currentSlide 2
***** dragEnd - relativeSlide 2 currentSlide 0
***** slideChanged - relativeSlide 3 currentSlide 0
****** currentSlide 3
****** currentSlide 3
***** dragEnd - relativeSlide 3 currentSlide 0
***** slideChanged - relativeSlide 4 currentSlide 0
****** currentSlide 4
****** currentSlide 4
***** dragEnd - relativeSlide 4 currentSlide 0
***** slideChanged - relativeSlide 5 currentSlide 0
****** currentSlide 5
****** currentSlide 5
***** dragEnd - relativeSlide 5 currentSlide 0
Seems like a scoping issue
According to the docs slides property should support array of raw html elements but when used with Vue $refs property it's not working as expected.
Reproduction link: https://codesandbox.io/s/keen-slider-default-vue-forked-zpkur?file=/src/Slider.vue
Expected result: slider initializes correctly when $refs is used
mind blowing pure work in super clean and easy to read JS. Wow, just wow. What do you think of sliders in sliders?
If you drag an element that has link, on mouse up, the link is fired. I tried the "data-keen-slider-pe" but it doesnt seem to solve the issue. Thank you
Although currently there is a way to display multiple slides per view I wasn't able to find any built it way to make it work properly with controls. Provided controls example only account for one slide per view, but what I would like to do is to slide per view when user clicks on the arrow or dot. Amount of dots should also represent the amount of views, not slides.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.