The bullet switches are slow
Greetings! How do I make the bullets switch on "run.before" event, not on "run.after"?
So far, I have done so, but it may be possible to do it more natively?
const ACTIVE_BULLET_CLASS_NAME = `glide__bullet--active`;
const BULLETS_CONTAINER_SELECTOR = `.glide__bullets`;
const changeActiveBullet = (newIndex, containerElement) => {
containerElement
.querySelector(`.${ACTIVE_BULLET_CLASS_NAME}`)
.classList.remove(ACTIVE_BULLET_CLASS_NAME);
containerElement
.querySelector(`[data-glide-dir="=${newIndex}"]`)
.classList.add(ACTIVE_BULLET_CLASS_NAME);
};
...
const sliderElement = document.querySelector(SLIDER_SELECTOR);
const bulletsContainerElement = sliderElement.querySelector(BULLETS_CONTAINER_SELECTOR);
sliderInstance.on(`run.before`, (moveOptions) =>
changeActiveBullet(moveOptions.steps, bulletsContainerElement)
);
Hi @AeShevch ,
can you more explain, how did you implement this fix? I am trying to fix it too. Thanks
I'm in the same boat. It feel extremely unnatural to see the bullet move after the animation.
Also, the above proposed code won't work in the case of using arrows. That only works when the bullet is clicked
+1
any update on this?
i had the same problem and fixed it by adding custom active classes like explained in this issue
import { siblings } from "@glidejs/glide/src/utils/dom";
// ...
const CustomActiveClass = (Glide, Components, Events) => {
const Component = {
mount() {
this.changeActiveSlide();
},
changeActiveSlide() {
const slide = Components.Html.slides[Glide.index];
const bullets = Components.Controls.items[0];
const bullet = [...bullets.children].find(
(bullet) => bullet.getAttribute("data-glide-dir") === `=${Glide.index}`
);
bullet.classList.remove("is-next", "is-prev");
bullet.classList.add("is-active");
slide.classList.remove("is-next", "is-prev");
slide.classList.add("is-active");
siblings(slide).forEach((sibling) => {
sibling.classList.remove("is-active", "is-next", "is-prev");
});
siblings(bullet).forEach((sibling) => {
sibling.classList.remove("is-active", "is-next", "is-prev");
});
if (slide.nextElementSibling) {
slide.nextElementSibling.classList.add("is-next");
}
if (slide.previousElementSibling) {
slide.previousElementSibling.classList.add("is-prev");
}
if (bullet.nextElementSibling) {
bullet.nextElementSibling.classList.add("is-next");
}
if (bullet.previousElementSibling) {
bullet.previousElementSibling.classList.add("is-prev");
}
},
};
Events.on("run", () => {
Component.changeActiveSlide();
});
return Component;
};
and then i registered it like so:
new Glide(element, {
// ...
}).mount({
// ...
CustomActiveClass,
});
now you could style your bullets according to the custom is-active class.
hope this helps :)
Here is the solution that worked for me:
const slider = document.querySelector('your-slider-container')
const activeBullet = "glide__bullet--active";
const bulletsContainerElement = slider.querySelector(".glide__bullets");
const changeActiveBullet = (newIndex, containerElement) => {
const glideDir = containerElement.querySelector(`[data-glide-dir="=${newIndex}"]`);
containerElement.querySelector(`.${activeBullet}`).classList.remove(activeBullet);
if (glideDir) glideDir.classList.add(activeBullet);
};
const glide = new Glide(slider, {
type: "carousel",
animationDuration: 1000,
}).mount();
glide.on("run", () => {
requestAnimationFrame(() => changeActiveBullet(glide.index, bulletsContainerElement));
});
imo this should be by default how the slider works.
Here is the solution that worked for me:
const slider = document.querySelector('your-slider-container') const activeBullet = "glide__bullet--active"; const bulletsContainerElement = slider.querySelector(".glide__bullets"); const changeActiveBullet = (newIndex, containerElement) => { const glideDir = containerElement.querySelector(`[data-glide-dir="=${newIndex}"]`); containerElement.querySelector(`.${activeBullet}`).classList.remove(activeBullet); if (glideDir) glideDir.classList.add(activeBullet); }; const glide = new Glide(slider, { type: "carousel", animationDuration: 1000, }).mount(); glide.on("run", () => { requestAnimationFrame(() => changeActiveBullet(glide.index, bulletsContainerElement)); });
Thank you, it is working perfectly. Def agree that this should be by default how the slider works.
Here's a Component that that achieves the same thing.
const NAV_SELECTOR = '[data-glide-el="controls[nav]"]'
const SetActiveBulletInstantly: ComponentFunction = (
Glide,
Components,
Events
) => {
let controlNavs: HTMLElement[] = []
return {
mount() {
controlNavs = Array.from(
Components.Html.root.querySelectorAll(NAV_SELECTOR)
)
Events.on('run', () => {
const settings = Glide.settings
const activeClass = settings.classes.nav.active
controlNavs.forEach((controlNav) => {
const activeItem = controlNav.children.item(
Glide.index
) as HTMLElement
controlNav.querySelectorAll(`.${activeClass}`).forEach((el) => {
el.classList.remove(activeClass)
})
activeItem.classList.add(activeClass)
})
})
},
}
}
Usage:
new Glide('.glide').mount({ SetActiveBulletInstantly })