-
Notifications
You must be signed in to change notification settings - Fork 601
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Disable prev/next buttons for contain #289
Comments
Yes, this is a tricky issue. I'll repeat my thoughts on why page dots and the prev/next buttons work with contain #177 (comment) and #135 (comment)
You can detect when the slider is at the end with flkty.on( 'cellSelect', function() {
var target = flkty.selectedCell.target;
if ( target == flkty.cells[0].target ) {
console.log('is at contained start')
} else if ( target == flkty.getLastCell().target ) {
console.log('is at contained end')
}
}); If you're looking to disable prev/next buttons, you could do it by hacking var PrevNextButton = Flickity.PrevNextButton;
PrevNextButton.prototype.update = function() {
// index of first or last cell, if previous or next
var cells = this.parent.cells;
// enable is wrapAround and at least 2 cells
if ( this.parent.options.wrapAround && cells.length > 1 ) {
this.enable();
return;
}
var lastIndex = cells.length ? cells.length - 1 : 0;
var boundIndex = this.isPrevious ? 0 : lastIndex;
var isEnabling;
if ( this.parent.options.contain ) {
var boundCell = cells[ boundIndex ];
var selectedCell = cells[ this.parent.selectedIndex ];
isEnabling = selectedCell.target != boundCell.target;
} else {
isEnabling = this.parent.selectedIndex == boundIndex
}
var method = isEnabling ? 'enable' : 'disable';
this[ method ]();
}; I do not recommend disabling buttons like this as selecting cells is useful for accessibility. |
Ah, I see that makes sense. This issue is indeed trickier than I thought. The examples are a great help, thank you! |
Re-opening for other's visibility |
Having the same issues, thanks for the demos @desandro, really really helpful man. However, I am still able to replicate the error by using a combination of dragging and clicking on prev/next. You can see it in both of the demos above. Start by dragging the slide to the very end (dragging left) until the last cell is highlighted in yellow. Wonder if would be worth having that as an option though, for example: Thanks a lot |
+1 I'm also still having issues with this when using a carousel as navigation for another carousel. The fact is that in this case an item in the carousel can be selected by the user. Therefore that item then has a class 'is-selected' and if this selected item is the last item in the carousel, and the carousel is cell-aligned to the center or to the left, a click on the left button doesn't move the carousel anymore. Even if the fix from above has been applied. |
Any update on this one @desandro? |
One solution is to use |
Also trying to solve this for a project with cell align left. Got this maybe working; Then u can bound the next button to a end. in the flickity create add in function: This: Then this.boundLastSlide has the last slider. On // Not all edits given. Only this doesn't solve the page dots, but can be a step to work with contain and the bounds. Maybe it can done better only in the post u made in nov 2015. #289 (comment) Demo Video https://www.youtube.com/watch?v=5Oy_nYpB4No |
I'm having a similar issue with this. Grouping fixes the disable issue but I only want to scroll one |
Usage: [object].flickity({ cellAlign: 'left', contain: true, wrapAround: false });
@wydflannery made this local in v1.2.1. ( because IE8 support needed 👎 ) and with settings:
Side note: I did not make a solution for the page dots. this would be simple with: boundLastSlide towards pageDots. In the function PageDots.prototype.setDots Here you can find the code. Compare: Maybe this feedback helps @desandro For the new version (2.0.x) you need to check all possible options in contain. |
Hey guys! If anyone still wondering about this, here is my solution: var carouselInit = new Flickity( '.carousel-init', {
cellSelector: '.carousel-cell',
contain: true,
cellAlign: 'left',
pageDots: false,
wrapAround: false,
freeScroll: false
});
var lastCell = false;
carouselInit.on('cellSelect', function(){
var friction = (carouselInit.options['friction'] + 0.1) * 1000;
setTimeout(function(){
var fullSize = carouselInit.slideableWidth,
viewport = carouselInit.size['width'],
cellWidth = carouselInit.selectedSlide['outerWidth'],
movedX = Math.round(carouselInit.x);
fullSize = Math.round(fullSize);
cellWidth = Math.round(cellWidth);
movedX = Math.abs(movedX);
var total = Math.round((viewport + movedX) / 100) * 100,
fullSize = Math.round(fullSize / 100) * 100;
if(total >= fullSize){
if(lastCell == true)
carouselInit.select(0);
lastCell = true;
}
if(movedX < 70)
lastCell = false
}, friction);
}); |
Another possible solution. new Flickity('.slider', {
contain: true,
pageDots: false,
cellAlign: "left",
selected: 0,
on: {
ready: containFix,
settle: containFix,
change: containFixOnChange,
resize: containFix
}
});
function containFix() {
const viewport = this.size.width;
const movedX = Math.round(Math.abs(this.x));
const total = viewport + movedX;
const fullSize = Math.round(this.slideableWidth);
toggle = toggle.bind(this);
toggle(total, fullSize, viewport);
}
function containFixOnChange() {
const viewport = this.size.width;
const cellWidth = this.selectedSlide.outerWidth;
if (this.selectedIndex > this.options.selected) var total = viewport + cellWidth * this.options.selected;
else if (this.selectedIndex < this.options.selected) var total = viewport - cellWidth * this.options.selected;
this.options.selected = this.selectedIndex;
const fullSize = Math.round(this.slideableWidth - cellWidth);
toggle = toggle.bind(this);
toggle(total, fullSize, viewport);
}
function toggle(total, fullSize, viewport) {
const cellWidth = this.selectedSlide.outerWidth;
const maxIdx = this.cells.length - Math.round(viewport / cellWidth);
if (fullSize > viewport) {
this.bindDrag();
this.element.classList.remove("slider--toggle-both");
} else if (fullSize <= viewport) {
this.unbindDrag();
this.element.classList.add("slider--toggle-both");
}
if (total >= fullSize) this.element.classList.add("slider--toggle-next");
else this.element.classList.remove("slider--toggle-next");
if (this.selectedIndex > maxIdx) {
this.select(maxIdx);
this.element.classList.add("slider--toggle-next");
}
} |
Another solution // This works if the cells are the same width and aligned center.
//
// If you have variants in your cell widths, you could loop through cells (beginning/end)
// to figure out which one will land on the middle of flkty.size.width
//
// Also you can extract the floor/ceil computations to a resize event if it becomes intensive.
flkty.on( 'change', i => {
// figure out the last/first slides
let floor = ~~(flkty.size.width / flkty.cells[0].element.offsetWidth / 2),
ceil = flkty.cells.length - floor;
// select the floor/ceil cells if the current index exceeds them
if(i > ceil) this.carousel.select(ceil);
else if (i < floor) this.carousel.select(floor);
}); |
Would PR #1032 potentially fix this as we are redefining what counts as selected? |
Hey. As for me, the easiest solution for this issue is to use the IntersectionObserver API. Just listen to the last slide to get into the viewport, then disable Next Button |
Hey, could you share an example please? |
@iriepixel const observer = new IntersectionObserver(
entries => {
entries.forEach(entry => {
if (entry.isIntersecting) {
controls.disableNext();
} else {
controls.enableNext();
}
});
},
{ rootMargin: '0px -24px 0px 0px', root: sliderNode }
);
observer.observe(lastSlide); where |
I used the on "scroll" function to check if the slider progress is 100%
|
I'm wondering if you have any suggestions for determining if you've arrived at the boundary of the carousel when the contain option is specified. (So that one could say for instance disable the next or previous buttons).
When not using the indicator dots for position feedback this kind of behavior appears confusing, though I understand the logic here.
Example:
The text was updated successfully, but these errors were encountered: