scrollowanie w górę - jaki warunek?

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)

   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'
                }
            })
            ```
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ół.

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

0

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

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

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.

1 użytkowników online, w tym zalogowanych: 0, gości: 1