|
3 weeks ago | |
---|---|---|
.. | ||
README.md | 3 weeks ago | |
assignment.md | 4 weeks ago |
README.md
Teraryum Projesi Bölüm 3: DOM Manipülasyonu ve Bir Closure
Sketchnote: Tomomi Imura
Ders Öncesi Test
Giriş
DOM veya "Document Object Model" manipülasyonu, web geliştirme sürecinin önemli bir parçasıdır. MDN'ye göre, "Document Object Model (DOM), web üzerindeki bir belgenin yapısını ve içeriğini oluşturan nesnelerin veri temsili şeklidir." Web'de DOM manipülasyonu ile ilgili zorluklar, genellikle JavaScript çerçevelerinin kullanılmasının temel nedenlerinden biri olmuştur. Ancak biz, vanilla JavaScript kullanarak bu işi kendimiz halledeceğiz!
Ayrıca, bu derste bir JavaScript closure fikrini tanıtacağız. Closure, bir fonksiyonun başka bir fonksiyon tarafından kapsanmasıdır ve bu sayede içteki fonksiyon, dıştaki fonksiyonun kapsamına erişebilir.
JavaScript closure'ları geniş ve karmaşık bir konudur. Bu derste, teraryum kodunda bir closure'ın temel fikrine değineceğiz: bir iç fonksiyon ve bir dış fonksiyon, iç fonksiyonun dış fonksiyonun kapsamına erişmesine izin verecek şekilde yapılandırılmıştır. Bu konunun nasıl çalıştığı hakkında daha fazla bilgi için kapsamlı dokümantasyonu ziyaret edebilirsiniz.
DOM'u manipüle etmek için bir closure kullanacağız.
DOM'u, bir web sayfası belgesinin manipüle edilebileceği tüm yolları temsil eden bir ağaç olarak düşünebilirsiniz. Programcıların tercih ettikleri programlama dillerini kullanarak DOM'a erişip düzenleme, değiştirme, yeniden düzenleme ve yönetme işlemleri yapabilmeleri için çeşitli API'ler (Uygulama Programlama Arayüzleri) yazılmıştır.
DOM'un ve onu referans alan HTML işaretlemesinin bir temsili. Kaynak: Olfa Nasraoui
Bu derste, kullanıcıların sayfadaki bitkileri manipüle etmesine olanak tanıyan JavaScript'i oluşturarak interaktif teraryum projemizi tamamlayacağız.
Önkoşul
Teraryumunuz için HTML ve CSS'in hazır olması gerekiyor. Bu dersin sonunda, bitkileri sürükleyerek teraryuma ekleyip çıkarabileceksiniz.
Görev
Teraryum klasörünüzde script.js
adında yeni bir dosya oluşturun. Bu dosyayı <head>
bölümüne şu şekilde ekleyin:
<script src="./script.js" defer></script>
Not: Bir JavaScript dosyasını HTML dosyasına dışarıdan eklerken
defer
kullanın, böylece JavaScript, HTML dosyası tamamen yüklendikten sonra çalışır. Alternatif olarak,async
özelliğini kullanabilirsiniz; bu, script'in HTML dosyası ayrıştırılırken çalışmasına izin verir. Ancak bizim durumumuzda, sürükleme işlemi başlamadan önce HTML öğelerinin tamamen hazır olması önemlidir.
DOM Öğeleri
İlk olarak, DOM'da manipüle etmek istediğiniz öğelere referanslar oluşturmanız gerekiyor. Bizim durumumuzda, bunlar yan çubuklarda bekleyen 14 bitkidir.
Görev
dragElement(document.getElementById('plant1'));
dragElement(document.getElementById('plant2'));
dragElement(document.getElementById('plant3'));
dragElement(document.getElementById('plant4'));
dragElement(document.getElementById('plant5'));
dragElement(document.getElementById('plant6'));
dragElement(document.getElementById('plant7'));
dragElement(document.getElementById('plant8'));
dragElement(document.getElementById('plant9'));
dragElement(document.getElementById('plant10'));
dragElement(document.getElementById('plant11'));
dragElement(document.getElementById('plant12'));
dragElement(document.getElementById('plant13'));
dragElement(document.getElementById('plant14'));
Burada ne oluyor? Belgeyi referans alıyor ve DOM'un içinde belirli bir Id'ye sahip bir öğe arıyorsunuz. HTML dersinin ilk bölümünde, her bir bitki görseline bireysel Id'ler verdiğinizi hatırlıyor musunuz (id="plant1"
) ? Şimdi bu çabayı kullanacaksınız. Her bir öğeyi tanımladıktan sonra, bu öğeyi birazdan oluşturacağınız dragElement
adlı bir fonksiyona aktarıyorsunuz. Böylece, HTML'deki öğe artık sürüklenebilir hale geliyor (veya birazdan gelecek).
✅ Neden öğelere Id ile referans veriyoruz? Neden CSS sınıfı ile değil? Bu sorunun cevabını CSS dersine geri dönerek bulabilirsiniz.
Closure
Şimdi, bir dış fonksiyonun bir veya daha fazla iç fonksiyonu kapsadığı dragElement
closure'ını oluşturmaya hazırsınız.
Closure'lar, bir veya daha fazla fonksiyonun dış fonksiyonun kapsamına erişmesi gerektiğinde kullanışlıdır. İşte bir örnek:
function displayCandy(){
let candy = ['jellybeans'];
function addCandy(candyType) {
candy.push(candyType)
}
addCandy('gumdrops');
}
displayCandy();
console.log(candy)
Bu örnekte, displayCandy
fonksiyonu, zaten fonksiyon içinde var olan bir diziye yeni bir şeker türü ekleyen bir fonksiyonu kapsar. Bu kodu çalıştırırsanız, candy
dizisi tanımsız olur çünkü bu dizi bir yerel değişkendir (closure'a özeldir).
✅ candy
dizisini nasıl erişilebilir hale getirebilirsiniz? Diziyi closure'ın dışına taşıyın. Bu şekilde, dizi global hale gelir ve closure'ın yerel kapsamıyla sınırlı kalmaz.
Görev
script.js
dosyasındaki öğe tanımlamalarının altına bir fonksiyon oluşturun:
function dragElement(terrariumElement) {
//set 4 positions for positioning on the screen
let pos1 = 0,
pos2 = 0,
pos3 = 0,
pos4 = 0;
terrariumElement.onpointerdown = pointerDrag;
}
dragElement
, terrariumElement
nesnesini script'in başındaki tanımlamalardan alır. Daha sonra, fonksiyona geçirilen nesne için bazı yerel pozisyonları 0
olarak ayarlarsınız. Bunlar, sürükleme ve bırakma işlevselliği eklerken her bir öğe için manipüle edilecek yerel değişkenlerdir. Teraryum, bu sürüklenen öğelerle doldurulacak, bu nedenle uygulamanın bu öğelerin nereye yerleştirildiğini takip etmesi gerekir.
Ayrıca, bu fonksiyona geçirilen terrariumElement
, bir pointerdown
olayı atanır. Bu olay, web API'lerinin bir parçasıdır ve DOM yönetimine yardımcı olmak için tasarlanmıştır. onpointerdown
, bir düğmeye basıldığında veya bizim durumumuzda, sürüklenebilir bir öğeye dokunulduğunda tetiklenir. Bu olay işleyici, birkaç istisna dışında hem web hem de mobil tarayıcılarda çalışır.
✅ onclick olay işleyicisinin tarayıcılar arası çok daha fazla desteği var; neden burada kullanmıyorsunuz? Burada oluşturmak istediğiniz ekran etkileşiminin tam türünü düşünün.
Pointerdrag Fonksiyonu
terrariumElement
, sürüklenmeye hazırdır; onpointerdown
olayı tetiklendiğinde, pointerDrag
fonksiyonu çağrılır. Bu satırın hemen altına bu fonksiyonu ekleyin: terrariumElement.onpointerdown = pointerDrag;
:
Görev
function pointerDrag(e) {
e.preventDefault();
console.log(e);
pos3 = e.clientX;
pos4 = e.clientY;
}
Birçok şey olur. İlk olarak, e.preventDefault();
kullanarak, pointerdown olayında normalde gerçekleşen varsayılan olayları engellersiniz. Bu şekilde, arayüzün davranışı üzerinde daha fazla kontrol sahibi olursunuz.
Script dosyasını tamamen oluşturduğunuzda bu satıra geri dönün ve
e.preventDefault()
olmadan deneyin - ne olur?
İkinci olarak, index.html
dosyasını bir tarayıcı penceresinde açın ve arayüzü inceleyin. Bir bitkiye tıkladığınızda, 'e' olayının nasıl yakalandığını görebilirsiniz. Olayın içine dalarak, bir pointerdown olayıyla ne kadar bilgi toplandığını inceleyin!
Son olarak, yerel değişkenler pos3
ve pos4
'ün e.clientX
değerine nasıl ayarlandığına dikkat edin. e
değerlerini inceleme panelinde bulabilirsiniz. Bu değerler, bitkiye tıkladığınız veya dokunduğunuz andaki x ve y koordinatlarını yakalar. Bitkilerin tıklanıp sürüklenmesi sırasında ince ayar yapmak için koordinatlarını takip etmeniz gerekir.
✅ Bu uygulamanın neden bir closure ile oluşturulduğu daha net hale geliyor mu? Eğer closure olmasaydı, 14 sürüklenebilir bitkinin kapsamını nasıl koruyabilirdiniz?
İlk fonksiyonu şu iki pointer olay manipülasyonunu ekleyerek tamamlayın:
document.onpointermove = elementDrag;
document.onpointerup = stopElementDrag;
Burada, bitkinin pointer ile birlikte sürüklenmesini ve bitkiyi seçmeyi bıraktığınızda sürükleme hareketinin durmasını istiyorsunuz. onpointermove
ve onpointerup
, onpointerdown
ile aynı API'nin bir parçasıdır. Arayüz şu anda hata verebilir çünkü elementDrag
ve stopElementDrag
fonksiyonlarını henüz tanımlamadınız, bu yüzden şimdi onları oluşturun.
ElementDrag ve StopElementDrag Fonksiyonları
Closure'ınızı, bir bitkiyi sürüklediğinizde ve sürüklemeyi bıraktığınızda ne olacağını yöneten iki dahili fonksiyon ekleyerek tamamlayacaksınız. İstediğiniz davranış, herhangi bir bitkiyi istediğiniz zaman sürükleyebilmeniz ve ekranın herhangi bir yerine yerleştirebilmenizdir. Bu arayüz oldukça esnektir (örneğin, bir bırakma alanı yoktur) ve bitkileri ekleyip çıkararak teraryumunuzu istediğiniz gibi tasarlamanıza olanak tanır.
Görev
pointerDrag
fonksiyonunun kapanış süslü parantezinin hemen altına elementDrag
fonksiyonunu ekleyin:
function elementDrag(e) {
pos1 = pos3 - e.clientX;
pos2 = pos4 - e.clientY;
pos3 = e.clientX;
pos4 = e.clientY;
console.log(pos1, pos2, pos3, pos4);
terrariumElement.style.top = terrariumElement.offsetTop - pos2 + 'px';
terrariumElement.style.left = terrariumElement.offsetLeft - pos1 + 'px';
}
Bu fonksiyonda, dış fonksiyonda yerel değişkenler olarak ayarladığınız pozisyonları (1-4) oldukça fazla düzenliyorsunuz. Burada ne oluyor?
Sürükleme sırasında, pos1
'i pos3
(daha önce e.clientX
olarak ayarladığınız) eksi mevcut e.clientX
değerine eşit yaparak yeniden atarsınız. Benzer bir işlemi pos2
için yaparsınız. Daha sonra, pos3
ve pos4
'ü öğenin yeni X ve Y koordinatlarına yeniden ayarlarsınız. Bu değişiklikleri sürüklerken konsolda izleyebilirsiniz. Daha sonra, bitkinin css stilini, yeni pozisyonlarına göre üst ve sol X ve Y koordinatlarını ayarlayarak manipüle edersiniz.
offsetTop
veoffsetLeft
, bir öğenin pozisyonunu, ebeveyninin pozisyonuna göre ayarlayan CSS özellikleridir; ebeveyni,static
olarak konumlandırılmamış herhangi bir öğe olabilir.
Bu pozisyonların yeniden hesaplanması, teraryumun ve bitkilerinin davranışını ince ayar yapmanıza olanak tanır.
Görev
Arayüzü tamamlamak için son görev, stopElementDrag
fonksiyonunu elementDrag
fonksiyonunun kapanış süslü parantezinin altına eklemektir:
function stopElementDrag() {
document.onpointerup = null;
document.onpointermove = null;
}
Bu küçük fonksiyon, onpointerup
ve onpointermove
olaylarını sıfırlar, böylece bitkinizin hareketini yeniden başlatabilir veya yeni bir bitkiyi sürüklemeye başlayabilirsiniz.
✅ Bu olayları null olarak ayarlamazsanız ne olur?
Artık projenizi tamamladınız!
🥇Tebrikler! Güzel teraryumunuzu tamamladınız.
🚀Meydan Okuma
Closure'ınıza bitkilerle ilgili başka bir şey yapmak için yeni bir olay işleyici ekleyin; örneğin, bir bitkiye çift tıklayarak onu öne getirin. Yaratıcı olun!
Ders Sonrası Test
İnceleme ve Kendi Kendine Çalışma
Ekranda öğeleri sürüklemek basit görünse de, bunu yapmanın birçok yolu ve istediğiniz etkiye bağlı olarak birçok tuzak vardır. Aslında, üzerinde çalışabileceğiniz bir sürükle ve bırak API'si vardır. Bu modülde kullanmadık çünkü istediğimiz etki biraz farklıydı, ancak bu API'yi kendi projenizde deneyin ve neler başarabileceğinizi görün.
Pointer olayları hakkında daha fazla bilgi için W3C belgelerine ve MDN web belgelerine göz atın.
Her zaman tarayıcı yeteneklerini CanIUse.com ile kontrol edin.
Ödev
Feragatname:
Bu belge, AI çeviri hizmeti Co-op Translator kullanılarak çevrilmiştir. Doğruluk için çaba göstersek de, otomatik çevirilerin hata veya yanlışlık içerebileceğini lütfen unutmayın. Belgenin orijinal dili, yetkili kaynak olarak kabul edilmelidir. Kritik bilgiler için profesyonel insan çevirisi önerilir. Bu çevirinin kullanımından kaynaklanan yanlış anlamalar veya yanlış yorumlamalar için sorumluluk kabul etmiyoruz.