Skip to content
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

[A11y] Activating pagination bullets with keyboard doesn't work when Swiper is first initialized with size 0 #7817

Open
6 tasks done
ReneZeidler opened this issue Dec 5, 2024 · 0 comments

Comments

@ReneZeidler
Copy link

ReneZeidler commented Dec 5, 2024

Check that this is really a bug

  • I confirm

Reproduction link

https://stackblitz.com/edit/swiper-pagination-a11y-bug

Bug description

I encountered an issue where sometimes the pagination bullets are not activatable by keyboard even though pagination.clickable is set to true. This happens when the swiper element has size 0 during initialization, e.g. because one of its parent elements is hidden. In the reproduction I've simulated this by wrapping it inside a hidden div that gets unhidden after a delay, but in practical use I've also encountered this when the swiper isn't intentionally hidden and just has size 0 due to some initialization logic.

I backtraced the issue:

  1. This is the code that adds the keyboard event listener to the pagination. It doesn't get run because hasClickablePagination() returns false.
    // Pagination
    if (hasClickablePagination()) {
    const paginationEl = makeElementsArray(swiper.pagination.el);
    paginationEl.forEach((el) => {
    el.addEventListener('keydown', onEnterOrSpaceKey);
    });
    }
  2. The method returns false because swiper.pagination.bullets.length is 0.
    function hasPagination() {
    return swiper.pagination && swiper.pagination.bullets && swiper.pagination.bullets.length;
    }
    function hasClickablePagination() {
    return hasPagination() && swiper.params.pagination.clickable;
    }
  3. The bullets array is empty because swiper.snapGrid is empty.
    : swiper.snapGrid.length;
  4. snapGrid is initialized to the empty array:
    snapGrid: [],

    Usually, if it's empty, it gets set to the 1-element array [0] here:
    if (snapGrid.length === 0) snapGrid = [0];

    However, that code doesn't get run because the function returns early when swiper.size is undefined:
    if (typeof swiperSize === 'undefined') {
    return;
    }
  5. Finally, swiper.size only gets set when it has a size > 0:
    const el = swiper.el;
    if (typeof swiper.params.width !== 'undefined' && swiper.params.width !== null) {
    width = swiper.params.width;
    } else {
    width = el.clientWidth;
    }
    if (typeof swiper.params.height !== 'undefined' && swiper.params.height !== null) {
    height = swiper.params.height;
    } else {
    height = el.clientHeight;
    }
    if ((width === 0 && swiper.isHorizontal()) || (height === 0 && swiper.isVertical())) {
    return;
    }

    When the swiper element is hidden during initialization, or has width 0 for some other reason, size doesn't get set.

I can see two potential fixes for this issue:

  • It seems like the check for bullets.length > 0 is unnecessary:
 function hasPagination() { 
-   return swiper.pagination && swiper.pagination.bullets && swiper.pagination.bullets.length;
+   return swiper.pagination && swiper.pagination.bullets;
 } 

The only place where bullets is accessed is here, and forEach is safe to call on an empty array:

swiper.pagination.bullets.forEach((bulletEl) => {

-      snapGrid: [],
+      snapGrid: [0],

However, since I don't know the codebase, I don't know if that breaks any assumptions elsewhere.

Either (or both) of these changes should fix the issue by not skipping the initialization in the a11y module where the pagination keydown listener gets added.

Expected Behavior

Focusing a clickable pagination bullet with the keyboard and then activating it with Enter or Space should switch to the corresponding slide.

Actual Behavior

Nothing happens.

Swiper version

11.1.15

Platform/Target and Browser Versions

Windows, Chrome 131/Firefox 131

Validations

  • Follow our Code of Conduct
  • Read the docs.
  • Check that there isn't already an issue that request the same feature to avoid creating a duplicate.
  • Make sure this is a Swiper issue and not a framework-specific issue

Would you like to open a PR for this bug?

  • I'm willing to open a PR
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant