glide icon indicating copy to clipboard operation
glide copied to clipboard

The bullet switches are slow

Open AeShevch opened this issue 5 years ago • 11 comments

Greetings! How do I make the bullets switch on "run.before" event, not on "run.after"?

AeShevch avatar Feb 15 '21 09:02 AeShevch

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)
);

AeShevch avatar Feb 15 '21 14:02 AeShevch

Hi @AeShevch ,

can you more explain, how did you implement this fix? I am trying to fix it too. Thanks

panjosef avatar Mar 08 '21 10:03 panjosef

I'm in the same boat. It feel extremely unnatural to see the bullet move after the animation.

whispernight avatar Apr 12 '21 20:04 whispernight

Also, the above proposed code won't work in the case of using arrows. That only works when the bullet is clicked

whispernight avatar Apr 12 '21 20:04 whispernight

+1

asaadmahmood avatar Jun 20 '21 10:06 asaadmahmood

any update on this?

motion-work avatar Jul 06 '21 21:07 motion-work

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 :)

benekoehler avatar Jul 08 '21 15:07 benekoehler

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));
});

motion-work avatar Jul 08 '21 18:07 motion-work

imo this should be by default how the slider works.

ineptian avatar May 14 '22 03:05 ineptian

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.

Ana-Maria95 avatar Jul 20 '23 12:07 Ana-Maria95

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 })

stefan-wiebe avatar Feb 06 '24 15:02 stefan-wiebe