viewport.client.ts 966 B

123456789101112131415161718192021222324252627282930
  1. export default defineNuxtPlugin(() => {
  2. if (!import.meta.client) return
  3. const root = document.documentElement
  4. let raf = 0
  5. const apply = () => {
  6. raf = 0
  7. // visualViewport.height is the "real" visible area on iOS Safari (addresses bottom bar + keyboard).
  8. const h = window.visualViewport?.height ?? window.innerHeight
  9. const vh = Math.max(0, h) * 0.01
  10. root.style.setProperty('--app-vh', `${vh}px`)
  11. }
  12. const schedule = () => {
  13. if (raf) return
  14. raf = window.requestAnimationFrame(apply)
  15. }
  16. schedule()
  17. window.addEventListener('resize', schedule, { passive: true })
  18. window.addEventListener('orientationchange', schedule, { passive: true })
  19. // iOS Safari: address bar show/hide + keyboard changes affect visualViewport.
  20. if (window.visualViewport) {
  21. window.visualViewport.addEventListener('resize', schedule, { passive: true })
  22. window.visualViewport.addEventListener('scroll', schedule, { passive: true })
  23. }
  24. })