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

Resizing on container resize instead of window resize #4019

Closed
2 of 3 tasks
ettoredn opened this issue Dec 8, 2020 · 5 comments
Closed
2 of 3 tasks

Resizing on container resize instead of window resize #4019

ettoredn opened this issue Dec 8, 2020 · 5 comments

Comments

@ettoredn
Copy link
Contributor

ettoredn commented Dec 8, 2020

This is a:

  • bug
  • enhancement
  • feature-discussion (RFC)

I'd like to suggest implementing the ResizeObserver API as proposed years ago in #2068 .

Browser support is now more widespread and this would really help in cases where CSS is loaded asynchronously ("non-critical"). Consider for instance this situation:

  • browser loads critical CSS and performs first paint
  • browser loads ES modules (swiper)
  • swiper.init()
  • async CSS is loaded that changes the size of .swiper-container

One reason to NOT implement the ResizeObserver API would be that if the slider is shown above-the-fold, then all .swiper-container's style should already be loaded and therefore there would be no problem. Otherwise, i.e. swiper loaded "below-the-fold", then lazy initialize it using IntersectionObserver as even async styles are likely to have been loaded at this point.

However, consider this case:

  • browser loads critical CSS and performs first paint
  • browser loads swiper via ES modules (deferred)
  • user scrolls
  • .swiper-container becomes visibile and swiper is initialized via IntersectionObserver
  • async "below-the-fold" CSS is loaded and resizes .swiper-container

This clearly breaks proper slide sizing which uses Swiper's internal methods updateSize() and updateSlides().

@ettoredn
Copy link
Contributor Author

ettoredn commented Dec 9, 2020

This is what I've come up with so far:

const ResizeObserver = {
	name: 'resize',
	create: (swiper: Swiper) => {
		Object.assign(swiper, {
			resizeObserver: null
		});
	},
	on: {
		init: (swiper: Swiper) => {
			const container = swiper.$el[0]
			console.debug(`Swiper.resizeObserver.init container=`, container);

			if (!('ResizeObserver' in window)) return;

			const observer = new ResizeObserver((entries) => {
				console.debug(entries);
				swiper.emit('observerUpdate');
			});

			observer.observe(container, {box: 'border-box'});

			swiper.resizeObserver = observer;
		}
	},
	destroy: (swiper: Swiper) => {
		console.debug(`Swiper.resizeObserver.destroy`);

		if (swiper.resizeObserver) {
			swiper.resizeObserver.disconnect();
		}
	}
} as SwiperComponent;

Use with Swiper.use([ResizeObserver]) and updateOnWindowResize: false.

It leverages events from the MutationObserver module (observer.js) to trigger onResize core handler.

I would go as far as saying that this should be integrated in modules/resize/resize.js as a replacement for window's resize event when ResizeObserver is available.

@nolimits4web
Copy link
Owner

Fixed with 5f80052

@ettoredn
Copy link
Contributor Author

ettoredn commented Mar 8, 2021

I've just tested v6.5.0 and resizing the viewport does not update swiper. I haven't had time to further investigate the issue, but for now I'm reverting to using my module.

@vltansky vltansky reopened this Mar 9, 2021
@nolimits4web
Copy link
Owner

If issue persists, please provide a live example/fiddle with the issue

@ettoredn
Copy link
Contributor Author

ettoredn commented Mar 21, 2021

I figured it out: in order for resizeObserver to work on .swiper-container, updateOnWindowResize must be set to true. I believe this should at the very least be mentioned in the docs.

Does enabling updateOnWindowResize result in the window.addEventListener('resize', ..) handler to be registered too? If so, the user should be given the option to disable the resize event listener thus use only ResizeObserver on the container for obvious performance reasons.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants