scrollowanie w górę - jaki warunek?

scrollowanie w górę - jaki warunek?
DC
  • Rejestracja:ponad 6 lat
  • Ostatnio:około 8 godzin
  • Postów:325
0

Hej, użytkownik mi podaje pozycje scrolla (góra/dół) kiedy ma się odpalić animacja oraz po ilu px w górę ma animacja wrocic do swojej pierwotnej postaci. Niestety scrollując w górę animacja mi nie działa. Prosze o pomoc
np attribute1 - 500 ( scroll w dół o 500 odpala się animacja)
attribute2 - 200 ( scroll w górę o 200 odpala się animacja)

Kopiuj
   let isScrolledUnderAttribute1 = false
     window.addEventListener(scroll , function () {
               let st = window.pageYOffset || document.documentElement.scrollTop;
               if (st > Number(attribute1)){
                   hat2.style.maxHeight='0'
                   hat2.style.marginBottom='0'
                   hat2.style.overflow='hidden'
                   hat2.style.transition='max-height .3s ease'
                   isScrolledUnderAttribute1= true;
                } 
                 if(isScrolledUnderAttribute1 && st <= st - Number(attribute2)) {
                   hat2.style.maxHeight='50px'
                   hat2.style.marginBottom='6px'
                   hat2.style.transition='max-height .3s ease'
                }
            })
            ```
edytowany 1x, ostatnio: cerrato
cerrato
Daj może jakiś działający przykład na https://jsfiddle.net/ - będzie o wiele łatwiej Ci pomóc.
Xarviel
  • Rejestracja:ponad 3 lata
  • Ostatnio:około 2 godziny
  • Postów:847
2

Można byłoby to zrobić za pomocą IntersectionObserver, ale jest to trochę trudniejsze od zwykłego eventu scroll.
https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API

Jeśli robimy to za pomocą eventu scroll to zrobiłbym coś takiego.

W zmiennej prevPosY zapisywana jest pozycja scrollbara i na podstawie tej wartości obliczam, w którą stronę przewija użytkownik góra / dół.

Kopiuj
const lorem = document.querySelector('.lorem');

const attribute1 = '200';
const attribute2 = '100';

//
//

let prevPosY = window.scrollY;

window.addEventListener('scroll' , function () {
  const currentPosition = prevPosY >= window.scrollY ? 'top' : 'bottom';

  if (currentPosition === 'bottom' && prevPosY > Number(attribute1)) {
     // zmiana styli / klasy css
  } else if(currentPosition === 'top' && prevPosY < Number(attribute2)) {
     // zmiana styli / klasy css
  }

  prevPosY = window.scrollY;
}, { passive: true });

Opcja { passive: true } w addEventListener pozwala poprawić delikatnie wydajność https://stackoverflow.com/questions/37721782/what-are-passive-event-listeners

EDIT:
Jeśli próbujesz zrobić taką samą animacje jak w przykładzie na codepen to zamiast zmiany max-height / margin-bottom robiłbym to za pomocą transform: translateY(-100px). To także poprawi wydajność animacji, bo animowanie takich wartości jak max-height nie jest zbyt dobre https://codeburst.io/low-performance-css-transitions-and-some-alternatives-f84ff35bf07

edytowany 3x, ostatnio: Xarviel
DC
  • Rejestracja:ponad 6 lat
  • Ostatnio:około 8 godzin
  • Postów:325
0

Tylko, ze ten warunek

Kopiuj
else if(currentPosition === 'top' && prevPosY < Number(attribute2))

wykona się wtedy gdy scrollując w górę scroll osiągnie 100px
a mi chodzi o to, ze jak np zjade 1000px w dół i wracając do góry o attribute2 (100px) wykonać zmiane styli, czyli jest to na poziomie 900px

edytowany 1x, ostatnio: cerrato
Xarviel
  • Rejestracja:ponad 3 lata
  • Ostatnio:około 2 godziny
  • Postów:847
2
dcielak napisał(a):

Tylko, ze ten warunek
else if(currentPosition === 'top' && prevPosY < Number(attribute2)) wykona się wtedy gdy scrollując w górę scroll osiągnie 100px
a mi chodzi o to, ze jak np zjade 1000px w dół i wracając do góry o attribute2 (100px) wykonać zmiane styli, czyli jest to na poziomie 900px

No okej, w takim razie trzeba odjąć jedną wartość od drugiej.

Mechanizm jest praktycznie identyczny, dochodzi nam dodatkowa zmienna prevAnimationAPosY do zapisania pozycji, w której wykonała się pierwsza animacja i lekko zmieniony else if

Kopiuj
const attribute1='200';

let prevAnimationAPosY = window.scrollY;
let prevPosY = window.scrollY;

window.addEventListener('scroll' , function () {
  const currentPosition = prevPosY >= window.scrollY ? 'top' : 'bottom';

  if (currentPosition === 'bottom' && prevPosY > Number(attribute1)) {
     // zmiana styli / klasy css
    
    prevAnimationAPosY = window.scrollY; // <-- Tutaj zapisujemy pozycję, w której wykonała się animacja
  } else if(currentPosition === 'top' && prevPosY < (prevAnimationAPosY - 100)) { // <-- Tutaj odejmujemy np 100 pikseli od tej pozycji i sprawdzamy, czy można animować
     // zmiana styli / klasy css
  }

  prevPosY = window.scrollY;
}, { passive: true });

Dolny warunek się zmienił i teraz jest coś takiego else if(currentPosition === 'top' && prevPosY < (prevAnimationAPosY - 100)).
Możesz używać stałej wartości tak jak w przykładzie, albo podstawić jakaś zmienną else if(currentPosition === 'top' && prevPosY < (prevAnimationAPosY - Number(attribute2))), tak jak wcześniej była brana wartość attribute2.

edytowany 1x, ostatnio: Xarviel
DC
dziękuję za poświęcony czas! Bardzo pomogło
Xarviel
fajnie, że pomogło ;)

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.