• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

question-closed Przesuwanie div'ów w React.js

Object Storage Arubacloud
+1 głos
351 wizyt
pytanie zadane 21 czerwca 2021 w JavaScript przez poldeeek Mądrala (5,980 p.)
zamknięte 21 czerwca 2021 przez poldeeek

Cześć, piszę prostą apkę, która pozwoli mi kliknąć na element i go przesunąć na stronie. Napisałem komponent Spider, który ma być "chwytany" i przesuwany. Nie wiem jednak czemu po odkliknięciu (mouseup) komponent wciąż się przesuwa, mimo że dwa ostatnie consol.logi z funkcji handleMouseUp pokazują, że metoda przypisana do eventu onmouseup jest poprawnie zmieniana na null.

 

const Spider: React.FC<ISpiderProps> = ({ initTop, initLeft }) => {
  const [top, setTop] = useState(initTop);
  const [left, setLeft] = useState(initLeft);
  const myRef = useRef<HTMLDivElement>(null);

  // const handleMouseMove = (e: globalThis.MouseEvent) => {};

  const handleMouseUp = (e: globalThis.MouseEvent) => {
    console.log('handleMouseUp');
    e = e || window.event;
    e.preventDefault();
    if (!myRef || !myRef.current) return;
    document.onmousemove = null;
    document.onmouseup = null;

    // TODO everything is null, but the objects are still moving after no mouse up
    console.log(document.onmouseup, myRef.current.onmouseup);
    console.log(document.onmousemove, myRef.current.onmousemove);
  };

  const handleMouseDown = (e: globalThis.MouseEvent) => {
    e = e || window.event;
    e.preventDefault();
    if (!myRef || !myRef.current) return;

    let pos1 = 0,
      pos2 = 0,
      pos3 = 0,
      pos4 = 0;

    // image position
    pos3 = e.clientX;
    pos4 = e.clientY;

    document.addEventListener('mouseup', handleMouseUp);

    document.addEventListener('mousemove', (e) => {
      console.log('mousemove');

      if (!myRef || !myRef.current) return;

      e = e || window.event;
      e.preventDefault();
      // calculate the new cursor position:
      pos1 = pos3 - e.clientX;
      pos2 = pos4 - e.clientY;
      pos3 = e.clientX;
      pos4 = e.clientY;

      // set the element's new position:
      myRef.current.style.top = myRef.current.offsetTop - pos2 + 'px';
      myRef.current.style.left = myRef.current.offsetLeft - pos1 + 'px';
    });
  };

  useEffect(() => {
    if (!myRef || !myRef.current) return;

    myRef.current.addEventListener('mousedown', handleMouseDown);

    return () => {
      if (!myRef || !myRef.current) return;
      myRef.current.removeEventListener('mousedown', handleMouseDown);
      document.removeEventListener('mouseup', handleMouseUp);
      document.onmousemove = null;
    };
  }, [myRef]);
  console.log(document.onmouseup);

  return (
    <div
      ref={myRef}
      draggable
      className='spider'
      style={{ top: top, left: left }}></div>
  );
};

 

komentarz zamknięcia: Rozwiązane

1 odpowiedź

+3 głosów
odpowiedź 21 czerwca 2021 przez ScriptyChris Mędrzec (190,190 p.)
wybrane 21 czerwca 2021 przez poldeeek
 
Najlepsza

Dlaczego podpinasz eventy poza kontekstem Reacta, zamiast skorzystać z handlerów w JSX? Poza tym mieszasz event listener z event handlerem.

Nie jestem pewien, czy to jest przyczyną, ale wydaje mi się, że jeśli trzymasz referencje do listenerów w zmiennej myRef, to pomiędzy kolejnymi renderami komponentu, ta referencja nie jest tą samą, którą początkowo używasz do dodania listenera - same funkcje handleMouseDown i handleMouseUp są ponownie tworzone między renderami, więc ich referencje zmieniają się. Upewnij się przed usunięciem, czy to są te same referencje, bo w przeciwnym wypadku removeEventListener nie zadziała.

Przydało by się też, żebyś podaj o tyle więcej kodu, żeby można było go uruchomić i przetestować. Wrzuć reprodukowalny fragment na np. https://codesandbox.io/

komentarz 21 czerwca 2021 przez poldeeek Mądrala (5,980 p.)
Nie wykorzystywałem tych handlerów, ponieważ wczoraj miałem z nimi jakieś dziwne problemy i chciałem najpierw to zrobić w taki sposób: https://www.w3schools.com/howto/howto_js_draggable.asp
Jednak zrobiłem przed chwilą drugie podejście z użyciem tych właśnie reactowych handlerów i wszystko działa jak powinno.

Podobne pytania

+2 głosów
0 odpowiedzi 280 wizyt
pytanie zadane 21 września 2021 w JavaScript przez gunaterek Bywalec (2,760 p.)
0 głosów
1 odpowiedź 190 wizyt
0 głosów
1 odpowiedź 309 wizyt
pytanie zadane 20 stycznia 2021 w JavaScript przez FoLONG Nowicjusz (160 p.)

92,576 zapytań

141,426 odpowiedzi

319,652 komentarzy

61,961 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...