React ile sürükleyerek kaydırılan bileşen nasıl yapılır?
React’te yatay bir alanı fareyle sürükleyerek kaydırmayı ve sürükleme sırasında yanlışlıkla tıklamayı önlemeyi anlattım.
Güncelleme:
Kodlamaya geçmeden önce hangi girdilere ihtiyacımız var onları belirlemeliyiz. Kaydırılabilir bir scroll yapmamız için öncelikle;
-
İki fare konumu arasındaki farkı piksel cinsinden hesaplamak.
-
Sürüklemenin başındaki scroll konumunu saklamak.
Mouse eventında mouse pozisyonumuzun tarayıcının görünüm alanı sınırlarına göre fare konumunun değerlerini (px) vereceğinden clientX ve clientY kullanacağız. Aşağıdaki görselde clientX ve clientY arasındaki fark görünüyor.
CLIENT → The Browser window
clientXclientY= values (px) of the mouse position relative to the Browser’s viewport boundaries.PAGE → The Whole Document
pageXpageY= values (px) of the mouse position relative to the Document most-top/left “sides”.SCREEN → Your Screen
screenXandscreenYare the values (px) of the current mouse position relative to the physical screen.
Soldaki görselde scrollTop ve scrollLeft bizim scroll pozisyonumuzun mevcut pixel değerlerini veriyor. Kısa bir özetin ardından şimdi biraz karmaşık olan kısma yani pozisyonları hesaplama kısmına bakalım.
İlk aşama
İlk önce mousedown eventında clientX, clientY, scrollTop ve scrollLeft değerlerini bir objede tutalım.
İkinci aşama
İkinci aşamada ise mousemove eventından gelen clientY değerini alalım. Hesaplamalarımızı mousemove üzerinden yapacağız. Çünkü burada mouse’a ön tıkladığımızda ve aşağı doğru sürüklediğimizde scroll konumunu güncellememiz gerekiyor.
Mousemove eventımızda biz farenin sol tıkına bastıktan sonra her mouse hareketinde çalışıyor. Buradaki mantık mousedown eventından alınan clientX, clientY değerleri mousemovedaki clientX,clientY değerlerinden çıkarıp bu farkı mousedown eventında aldığımız mevcut scrollTop ve scrollLeft değerlerini çıkarmak.
Sonrasında scrollTop ve scrollLeft ile elementimizin scroll pozisyonlarını güncellemek. Böyle olmasının sebebini aşağıdaki resimde gösteriyorum.
Aslında her şey iki mouse pozisyonunun arasındaki farktan ne kadar pixel pozisyon değiştirmemiz gerektiğini hesaplayıp, bu farkıda scrollToptan çıkartarak pozisyonumuzu güncellememizden ibaret. Buradaki önemli nokta mousedown eventımızda pozisyonların değerlerini kaydetmemiz.
Şimdi bu componentimizin childrenlarında buttonlar vs. olabilir ve sürükleme işlemi yapmak istediğimizde bu butonlara tıklayabiliyoruz malesefki bubbling etkisi oluyor. Bunu çözmek için kısa sürekiğine componentimizin ilk child ögesine pointerEvent özelliğini none yaparak js eventlarına kapatıyoruz ve böylece sorun ortadan kalkıyor
Sürükleme esnasında Componentimizin içerisindeki butonlara tıklamayı engelleme
sadece mousedown işlevimizin içerisinde setTimeout kullanarak
Örnekte 250 milisaniye sonra alt öğelerin pointer olaylarını kapatıyoruz. eğer 250 milisaniyeden önce mouseup eventımız çalışırsa onun içerisinde de clearTimeout ile bu timeoutu sonlandırıyor ve pointereventlarımızı açıyoruz.
Kullanıcının scroll yaparken yazıları seçmesini engellemek için userSelect i none yapıyoruz eventları elementimizi değilde document üzerinden çağırmamızın sebebi mousedown iken mouse umuzu elementimizin dışına çıkardığımızda ve mouseup yaptığımızda sol tıktan parmağımızı çektığımızde ve mouse mizi tekrar elementin üzerine getirdiğimizde hala mousedown eventında kalmasıdır deneyebilirsiniz.
Bunun nedenide aslında elementimizin içerisinde gerçekleşen bir mouseup olay olmadığından görmemesi normal.
Son olarak childrenlarımızı return fonksiyonumuzun içerisine yerleştiriyoruz ve artık bu bileşenin içindeki her şey sürüklenebilir scrolla sahip oldu.
kodların tam hali codesandbox ta ama orada scrollTo eventını çalıştıramadım ne kadar denesemde ama normalde çalışıyor
Bu örnek fare olaylarıyla yazılmıştı. Aynı davranışı fare ve dokunma için kuracaksan Pointer Events kullanabilirsin. Dinleyicileri ve zamanlayıcıları bileşen kaldırıldığında temizle. Bir tıklamayı sürükleme olarak saymak için yalnızca süreye bakmak yerine hareket mesafesini de ölç.