JavaScript etkinlik ayrıntılı incelemesi

preventDefault ve stopPropagation: Hangi yöntemin tam olarak ne zaman kullanılacağı ve her bir yöntemin tam olarak ne işe yaradığı.

Event.stopPropagation() ve Event.preventDefault()

JavaScript olaylarının işlenmesi genellikle basittir. Bu, özellikle basit (nispeten düz) bir HTML yapısı için geçerlidir. Ancak olaylar bir öğe hiyerarşisi boyunca ilerlerken (ya da yayılırken) işler biraz daha karmaşık hale gelir. Bu genellikle, geliştiriciler karşılaştıkları sorunları çözmek için stopPropagation() ve/veya preventDefault() ile iletişim kurduğunda gerçekleşir. "preventDefault()'i deneyeceğim. İşe yaramazsa stopPropagation() demeyi denerim, bu da işe yaramazsa her ikisini de deneyeceğim" diye düşündüyseniz bu makale tam size göre! Her yöntemin ne işe yaradığını ve ne zaman kullanılacağını tam olarak açıklayacağım ve incelemeniz için size çeşitli çalışan örnekler vereceğim. Amacım bu karışıklığı ortadan kaldırmak.

Konunun daha da derinlerine inmeden önce, JavaScript'te mümkün olan iki etkinlik işleme türüne kısaca değinmek önemlidir (yani, sürüm 9'dan önceki tüm modern tarayıcılarda etkinlik yakalamayı hiç desteklemiyordu).

Etkinlik oluşturma stilleri (yakalama ve baloncuk oluşturma)

Tüm modern tarayıcılar olay yakalamayı destekler, ancak geliştiriciler tarafından çok nadiren kullanılır. İşin ilginç yanı, Netscape'in ilk başta desteklediği tek etkinlik biçimi buydu. Netscape'in en büyük rakibi Microsoft Internet Explorer, etkinlik yakalamayı hiç desteklemiyordu. Yalnızca etkinlik balonları adı verilen başka bir etkinlik stilini destekliyordu. W3C oluşturulduğunda, her iki etkinlik tarzını da başarılı bulmuş ve tarayıcıların addEventListener yöntemine üçüncü bir parametre ile her ikisini de desteklemesi gerektiğini beyan etmiştir. Bu parametre başlangıçta yalnızca bir boole'ydi, ancak tüm modern tarayıcılar üçüncü parametre olarak bir options nesnesini destekler. Bu nesneyi, etkinlik yakalamayı kullanmak isteyip istemediğinizi belirtmek için (diğer şeylerin yanı sıra) kullanabilirsiniz:

someElement.addEventListener('click', myClickHandler, { capture: true | false });

options nesnesinin ve capture özelliğinin isteğe bağlı olduğunu unutmayın. Bunlardan biri atlanırsa capture için varsayılan değer false olur. Diğer bir deyişle, etkinlik baloncuğu kullanılır.

Etkinlik yakalama

Etkinlik işleyicinizin "yakalama aşamasında dinliyor olması" ne anlama gelir? Bunu anlamak için olayların nasıl ortaya çıktığını ve nasıl ilerlediğini bilmemiz gerekir. Geliştirici olarak bu etkinlikleri kullanmasanız, önemsemiyor veya düşünmeseniz bile tüm etkinlikler için aşağıdakiler geçerlidir.

Tüm etkinlikler pencerede başlar ve önce yakalama aşamasından geçer. Bu, bir etkinlik gönderildiğinde pencereyi başlattığı ve ilk olarak hedef öğesine doğru "aşağı doğru" ilerlediği anlamına gelir. Bu durum, yalnızca balonlaşma aşamasında dinleseniz bile geçerlidir. Aşağıdaki örnek işaretlemeyi ve JavaScript'i inceleyin:

<html>
  <body>
    <div id="A">
      <div id="B">
        <div id="C"></div>
      </div>
    </div>
  </body>
</html>
document.getElementById('C').addEventListener(
  'click',
  function (e) {
    console.log('#C was clicked');
  },
  true,
);

Bir kullanıcı #C öğesini tıkladığında, kaynağı window olan bir etkinlik gönderilir. Daha sonra bu etkinlik, alt öğeleri arasında aşağıdaki gibi yayılır:

window => document => <html> => <body> => ve diğerleri hedefe ulaşana kadar devam eder.

Tıklama etkinliğini window veya document ya da <html> öğesinde veya <body> öğesinde (ya da hedefine giden başka bir öğede) herhangi bir şeyin dinlememesi önemli değildir. Bir etkinliğin kaynağı yine window ve yolculuğu az önce açıklandığı şekilde başlar.

Örneğimizde, tıklama etkinliği daha sonra window ile #C arasındaki her öğe aracılığıyla window öğesinden hedef öğesine (bu örnekte #C) yaygın (bu, stopPropagation() yönteminin çalışma şekliyle doğrudan ilişkili olduğundan önemli bir kelimedir).

Bu, tıklama etkinliğinin window tarihinde başlayacağı ve tarayıcının aşağıdaki soruları soracağı anlamına gelir:

"Yakalama aşamasında window öğesinde tıklama etkinliğini dinleyen herhangi bir şey var mı?" Bu durumda uygun etkinlik işleyiciler etkinleşir. Örneğimizde hiçbir şey olmadığından hiçbir işleyici tetiklenmez.

Daha sonra, etkinlik document'a yayılır ve tarayıcı şu soruyu sorar: "Yakalama aşamasında document üzerindeki bir tıklama etkinliğini dinleyen herhangi bir şey var mı?" Böyle bir durumda, uygun etkinlik işleyiciler etkinleşir.

Daha sonra, etkinlik <html> öğesine yayılır ve tarayıcı şu soruyu sorar: "Yakalama aşamasında <html> öğesine yapılan tıklama için bekleyen bir şey var mı?" Bu durumda, uygun etkinlik işleyicileri etkinleşir.

Daha sonra, etkinlik <body> öğesine yayılır ve tarayıcı şu soruyu sorar: "Yakalama aşamasında <body> öğesinde bir tıklama etkinliği dinleyen herhangi bir şey var mı?" Bu durumda uygun etkinlik işleyiciler etkinleşir.

Daha sonra, etkinlik #A öğesine yayılır. Tarayıcı tekrar şu soruyu sorar: "Yakalama aşamasında #A üzerinde tıklama etkinliği dinleyen herhangi bir şey olup olmadığı ve böyle bir durumda uygun etkinlik işleyiciler tetiklenir.

Daha sonra, etkinlik #B öğesine yayılır (aynı soru sorulur).

Son olarak, etkinlik hedefine ulaşır ve tarayıcı şu soruyu sorar: "Yakalama aşamasında #C öğesindeki tıklama etkinliğini dinleyen bir şey var mı?" Bu sefer cevap "evet!" Etkinliğin hedef üzerinde olduğu bu kısa süre, "hedef aşama" olarak bilinir. Bu noktada, etkinlik işleyici etkinleşir ve tarayıcı console.log "#C tıklandığında" işlemini tamamlar, değil mi? Yanlış! Henüz işimiz bitmedi. Süreç devam eder ancak şimdi kaynaşma aşamasına geçilir.

Etkinlik baloncukları

Tarayıcı şu soruyu sorar:

"Köpürtme aşamasında #C üzerinde bir tıklama etkinliğini dinleyen herhangi bir şey var mı?" Buraya çok dikkat edin. Tıklamaları (veya herhangi bir etkinlik türünü) hemhem de kabarcıklaşma aşamalarında dinlemek tamamen mümkündür. Her iki aşamada da etkinlik işleyicileri yapılandırdıysanız (ör. .addEventListener() yöntemini iki kez, capture = true ile bir kez ve capture = false ile bir kez çağırarak) her iki etkinlik işleyici de aynı öğe için kesinlikle etkinleşir. Ancak bu etkileşimlerin farklı aşamalarda (biri yakalama aşamasında, diğeri kaynaşma aşamasında) tetiklendiğini de unutmamak gerekir.

Daha sonra, etkinlik üst öğesine (#B) yayılır (daha çok "balon" olarak adlandırılır, çünkü etkinlik DOM ağacında "yukarı" gidiyormuş gibi görünür) ve tarayıcı şu soruyu sorar: "Köpürtme aşamasında #B üzerindeki tıklama etkinliklerini dinleyen herhangi bir şey var mı?" Örneğimizde hiçbir şey olmadığından hiçbir işleyici tetiklenmez.

Daha sonra, etkinlik #A baloncuk olarak gösterilir ve tarayıcı şu soruyu sorar: "Kaynaşma aşamasında #A üzerinde tıklama etkinliklerini dinleyen bir şey var mı?"

Ardından etkinlik <body> olarak baloncuk olarak gösterilir: "Kaynaşma aşamasında <body> öğesindeki tıklama etkinliklerini dinleyen herhangi bir şey var mı?"

Daha sonra, <html> öğesi: "Kabarcık oluşturma aşamasında <html> öğesindeki tıklama etkinliklerini dinleyen herhangi bir şey var mı?

Sonra document: "Köpürtme aşamasında document üzerindeki tıklama etkinliklerini dinleyen herhangi bir şey var mı?"

Son olarak window: "Kaynaşma aşamasında pencerede tıklama etkinliklerini dinleyen herhangi bir şey var mı?"

Bora Uzun bir yolculuk oldu ve etkinliğimiz muhtemelen şu ana kadar çok yorucu oldu ama ister inanın ister inanmayın, her etkinlik bu yolculuktan geçer. Geliştiriciler genellikle sadece bir etkinlik aşamasıyla (ve genellikle balonlaşma aşamasıyla) ilgilendikleri için bu durum çoğu zaman fark edilmez.

Etkinlik yakalama, etkinlik baloncuğu oluşturma ve işleyiciler etkinleştiğinde konsola bazı notlar kaydetme konularında biraz zaman ayırmaya değer. Bir olayın izlediği yolu görmek çok bilgilendirici olacaktır. Burada, her iki aşamada da her öğeyi dinleyen bir örnek verilmiştir.

<html>
  <body>
    <div id="A">
      <div id="B">
        <div id="C"></div>
      </div>
    </div>
  </body>
</html>
document.addEventListener(
  'click',
  function (e) {
    console.log('click on document in capturing phase');
  },
  true,
);
// document.documentElement == <html>
document.documentElement.addEventListener(
  'click',
  function (e) {
    console.log('click on <html> in capturing phase');
  },
  true,
);
document.body.addEventListener(
  'click',
  function (e) {
    console.log('click on <body> in capturing phase');
  },
  true,
);
document.getElementById('A').addEventListener(
  'click',
  function (e) {
    console.log('click on #A in capturing phase');
  },
  true,
);
document.getElementById('B').addEventListener(
  'click',
  function (e) {
    console.log('click on #B in capturing phase');
  },
  true,
);
document.getElementById('C').addEventListener(
  'click',
  function (e) {
    console.log('click on #C in capturing phase');
  },
  true,
);

document.addEventListener(
  'click',
  function (e) {
    console.log('click on document in bubbling phase');
  },
  false,
);
// document.documentElement == <html>
document.documentElement.addEventListener(
  'click',
  function (e) {
    console.log('click on <html> in bubbling phase');
  },
  false,
);
document.body.addEventListener(
  'click',
  function (e) {
    console.log('click on <body> in bubbling phase');
  },
  false,
);
document.getElementById('A').addEventListener(
  'click',
  function (e) {
    console.log('click on #A in bubbling phase');
  },
  false,
);
document.getElementById('B').addEventListener(
  'click',
  function (e) {
    console.log('click on #B in bubbling phase');
  },
  false,
);
document.getElementById('C').addEventListener(
  'click',
  function (e) {
    console.log('click on #C in bubbling phase');
  },
  false,
);

Konsol çıkışı, tıkladığınız öğeye bağlıdır. DOM ağacındaki "en derin" öğeyi (#C öğesi) tıklarsanız bu etkinlik işleyicilerin her birini etkinleşirsiniz. Hangi öğenin hangisi olduğunu daha açık hale getirecek bir miktar CSS stiliyle konsol çıkışı #C öğesini burada görebilirsiniz (ekran görüntüsüyle birlikte):

"click on document in capturing phase"
"click on <html> in capturing phase"
"click on <body> in capturing phase"
"click on #A in capturing phase"
"click on #B in capturing phase"
"click on #C in capturing phase"
"click on #C in bubbling phase"
"click on #B in bubbling phase"
"click on #A in bubbling phase"
"click on <body> in bubbling phase"
"click on <html> in bubbling phase"
"click on document in bubbling phase"

Aşağıdaki canlı demoda bu oyunu etkileşimli olarak oynayabilirsiniz. #C öğesini tıklayın ve konsol çıkışını gözlemleyin.

event.stopPropagation()

Etkinliklerin nereden kaynaklandığını ve hem yakalama aşamasında hem de kaynaşma aşamasında DOM üzerinden nasıl ilerlediğini (yani yayıldığını) anlayarak artık dikkatimizi event.stopPropagation() kavramına çevirebiliriz.

stopPropagation() yöntemi, (çoğu) yerel DOM etkinliğinde çağrılabilir. "Çoğu" diyorum çünkü bu yöntemin çağrılmasının hiçbir şeye yol açmayacağı birkaç tane var (çünkü bu etkinlik başlangıç olarak yayılmaz). focus, blur, load, scroll ve diğer birkaç etkinlik bu kategoriye girer. stopPropagation() çağırabilirsiniz, ancak bu etkinlikler yayılmadığı için ilginç bir şey olmaz.

Peki stopPropagation ne yapar?

Aynen söylediğin şeyi yapıyor. Etkinlik çağırıldığında bu noktadan sonra, başka herhangi bir şekilde gideceği öğelere yayılmaya başlar. Bu, her iki yön için de (yakalama ve baloncuk çekme) geçerlidir. Dolayısıyla, yakalama aşamasında herhangi bir yerde stopPropagation() yöntemini çağırırsanız etkinlik hiçbir zaman hedef aşamasına veya kaynaşma aşamasına geçemez. Kabartma aşamasında çağırırsanız yakalama aşamasından geçmiş olur ancak sizin çağırdığınız andan itibaren artık "çıkırma" yaşanmaz.

Aynı örnek işaretlememize dönersek #B öğesindeki yakalama aşamasında stopPropagation() çağrısı yapsak ne olur?

Sonuç olarak şu çıktı elde edilir:

"click on document in capturing phase"
"click on <html> in capturing phase"
"click on <body> in capturing phase"
"click on #A in capturing phase"
"click on #B in capturing phase"

Aşağıdaki canlı demoda bu oyunu etkileşimli olarak oynayabilirsiniz. Canlı demoda #C öğesini tıklayıp konsol çıkışını gözlemleyin.

Baloncuk oluşturma aşamasında, dağıtımı #A düzeyinde durdurmaya ne dersiniz? Bu durumda aşağıdaki çıkış elde edilir:

"click on document in capturing phase"
"click on <html> in capturing phase"
"click on <body> in capturing phase"
"click on #A in capturing phase"
"click on #B in capturing phase"
"click on #C in capturing phase"
"click on #C in bubbling phase"
"click on #B in bubbling phase"
"click on #A in bubbling phase"

Aşağıdaki canlı demoda bu oyunu etkileşimli olarak oynayabilirsiniz. Canlı demoda #C öğesini tıklayıp konsol çıkışını gözlemleyin.

Sadece eğlenmek için bir soru daha. #C için hedef aşamada stopPropagation() çağrısı yaparsak ne olur? "Hedef aşamanın", etkinliğin hedeflediği halde olduğu döneme verilen ad olduğunu unutmayın. Sonuç olarak şu çıktı elde edilir:

"click on document in capturing phase"
"click on <html> in capturing phase"
"click on <body> in capturing phase"
"click on #A in capturing phase"
"click on #B in capturing phase"
"click on #C in capturing phase"

"Yakalama aşamasında #C'yi tıklama" işlemini günlüğe kaydettiğimiz #C olay işleyicisinin hâlâ yürütülürken "kaynaşma aşamasında #C tıklamasını" günlüğe kaydettiğimiz olay işleyicinin yürütülmediğini unutmayın. Bu açıklamanın çok mantıklı olması gerekir. stopPropagation() öğesini eskisinden kaynak çağırdık. Bu noktada, etkinliğin yayılımı sona erecektir.

Aşağıdaki canlı demoda bu oyunu etkileşimli olarak oynayabilirsiniz. Canlı demoda #C öğesini tıklayıp konsol çıkışını gözlemleyin.

Buradaki canlı demolardan birinde denemeler yapmanızı öneririm. Yalnızca #A öğesini veya yalnızca body öğesini tıklamayı deneyin. Neler olacağını tahmin etmeye çalışın ve yanıtınızın doğru olup olmadığını gözlemleyin. Bu noktada, oldukça doğru bir şekilde tahminde bulunabilmeniz gerekir.

event.stopImmediatePropagation()

Bu ilginç olan ve sık kullanılmayan yöntem nedir? stopPropagation'e benzer ancak bu yöntem, bir etkinliğin alt gruplara gitmesini durdurmak (yakalama) veya üst öğe (baloncuk oluşumu) ile ilerlemesini durdurmak yerine yalnızca tek bir öğeye bağlı birden fazla etkinlik işleyici olduğunda geçerlidir. addEventListener(), çoklu yayın tarzını desteklediğinden bir etkinlik işleyiciyi tek bir öğeye birden çok kez bağlamak tamamen mümkündür. Bu durumda, çoğu tarayıcıda etkinlik işleyiciler yapılandırıldıkları sırayla yürütülür. stopImmediatePropagation() çağrısı, sonraki işleyicilerin etkinleşmesini engeller. Aşağıdaki örneği inceleyin:

<html>
  <body>
    <div id="A">I am the #A element</div>
  </body>
</html>
document.getElementById('A').addEventListener(
  'click',
  function (e) {
    console.log('When #A is clicked, I shall run first!');
  },
  false,
);

document.getElementById('A').addEventListener(
  'click',
  function (e) {
    console.log('When #A is clicked, I shall run second!');
    e.stopImmediatePropagation();
  },
  false,
);

document.getElementById('A').addEventListener(
  'click',
  function (e) {
    console.log('When #A is clicked, I would have run third, if not for stopImmediatePropagation');
  },
  false,
);

Yukarıdaki örnek, aşağıdaki konsol çıkışıyla sonuçlanır:

"When #A is clicked, I shall run first!"
"When #A is clicked, I shall run second!"

İkinci etkinlik işleyicinin e.stopImmediatePropagation() yöntemini çağırması nedeniyle üçüncü etkinlik işleyicinin hiçbir zaman çalışmadığını unutmayın. Bunun yerine e.stopPropagation() çağrısı yapsak üçüncü işleyici çalışmaya devam ederdi.

event.preventDefault()

stopPropagation() bir etkinliğin "aşağı doğru" (yakalama) veya "yukarı" (kabarcıklı) ilerlemesini engellerse preventDefault() ne yapar? Sanki benzer bir şey yapıyormuş gibi duruyor. Öyle mi?

Pek sayılmaz. İkisi çoğu zaman birbirine karıştırılsa da aslında birbirleriyle pek bir ilgisi yoktur. preventDefault() ifadesini gördüğünüzde, kafanıza "işlem" kelimesini ekleyin. "Varsayılan eylemi engelleme" düşünün.

Varsayılan olarak hangi işlemi sorabilirsiniz? Ne yazık ki bunun yanıtı, büyük ölçüde söz konusu öğe + etkinlik kombinasyonuna bağlı olduğundan pek net değil. Konuları daha da karmaşık hale getirmek için bazen varsayılan bir işlem yoktur!

Anlaşılması için çok basit bir örnekle başlayalım. Bir web sayfasındaki bağlantıyı tıkladığınızda ne olmasını bekliyorsunuz? Elbette, tarayıcının bu bağlantıyla belirtilen URL'ye gitmesini beklersiniz. Bu durumda, öğe bir bağlantı etiketi ve etkinlik bir tıklama etkinliğidir. Bu kombinasyon (<a> + click), bağlantının href'e gitme"varsayılan işlemine" sahiptir. Tarayıcının bu varsayılan işlemi gerçekleştirmesini engellemek istiyorsanız ne olur? Yani tarayıcının, <a> öğesinin href özelliği tarafından belirtilen URL'ye gitmesini engellemek istediğinizi varsayalım. preventDefault() bunu sizin için yapacaktır. Aşağıdaki örneğe bakın:

<a id="avett" href="https://www.theavettbrothers.com/welcome">The Avett Brothers</a>
document.getElementById('avett').addEventListener(
  'click',
  function (e) {
    e.preventDefault();
    console.log('Maybe we should just play some of their music right here instead?');
  },
  false,
);

Aşağıdaki canlı demoda bu oyunu etkileşimli olarak oynayabilirsiniz. Avett Brothers bağlantısını tıklayın ve konsol çıkışını (ve Avett Brothers web sitesine yönlendirilmediğinizi) gözlemleyin.

Normalde, Avett Kardeşler etiketli bağlantıyı tıklamak, www.theavettbrothers.com sayfasına göz atılmasıyla sonuçlanır. Yine de bu örnekte, <a> öğesine bir tıklama etkinlik işleyicisi bağladık ve varsayılan işlemin engellenmesi gerektiğini belirttik. Böylece, kullanıcı bu bağlantıyı tıkladığında herhangi bir yerde gezinmez

Başka hangi öğe/etkinlik kombinasyonları varsayılan işlemi engellemenize olanak tanır? Hepsini sayamam, bazen görmek için yalnızca denemeler yapmanız gerekebilir. Ancak kısaca bunlardan bazılarını aşağıda bulabilirsiniz:

  • <form> öğesi + "submit" etkinliği: Bu kombinasyon için preventDefault(), formun gönderilmesini engeller. Bu, doğrulama gerçekleştirmek istiyorsanız ve bir şey başarısız olursa formun gönderilmesini durdurmak için koşullu olarak preventDefault çağırabilirsiniz.

  • <a> öğesi + "click" etkinliği: Bu kombinasyon için preventDefault(), tarayıcının <a> öğesinin href özelliğinde belirtilen URL'ye gitmesini engeller.

  • document + "mousewheel" etkinliği: preventDefault() bu kombinasyon için fare tekerleğiyle sayfa kaydırmayı engelliyor (klavyeyle kaydırma yine de işe yarayacaktır).
    ↜ Bunun için addEventListener() { passive: false } ile çağrılmalıdır.

  • document + "keydown" etkinliği: preventDefault() bu kombinasyon için ölümcül. Sayfayı büyük ölçüde işe yaramaz hale getirerek klavye kaydırmasını, sekme tuşu kullanımını ve klavye vurgulamasını önler.

  • document + "mousedown" etkinliği: preventDefault(), bu kombinasyon için metnin fare ile vurgulanmasını ve fare aşağı ile çağrılacağı diğer "varsayılan" işlemleri engeller.

  • Bu kombinasyon için <input> öğesi + "keypress" etkinliği: preventDefault(), kullanıcı tarafından yazılan karakterlerin giriş öğesine ulaşmasını engeller (ancak bunu yapmayın; nadiren geçerli bir neden olabilir).

  • document + "contextmenu" etkinliği: preventDefault(), kullanıcı sağ tıkladığında veya uzun bastığında (ya da içerik menüsünün görünebileceği başka herhangi bir şekilde) yerel tarayıcı içerik menüsünün görünmesini engeller.

Bu liste her ne olursa olsun kapsamlı bir liste değildir ancak preventDefault() özelliğinin nasıl kullanılabileceğine dair iyi bir fikir vereceğini umuyoruz.

Eğlenceli bir espri?

Siz stopPropagation() ve preventDefault(), belgeden başlayarak yakalama aşamasında olursa ne olur? Eğlence başlıyor! Aşağıdaki kod snippet'i, herhangi bir web sayfasını neredeyse tamamen işe yaramaz hale getirir:

function preventEverything(e) {
  e.preventDefault();
  e.stopPropagation();
  e.stopImmediatePropagation();
}

document.addEventListener('click', preventEverything, true);
document.addEventListener('keydown', preventEverything, true);
document.addEventListener('mousedown', preventEverything, true);
document.addEventListener('contextmenu', preventEverything, true);
document.addEventListener('mousewheel', preventEverything, { capture: true, passive: false });

Bunu neden yapmak isteyebileceğini gerçekten bilmiyorum (birisine şaka yapmak dışında) ama burada neler olup bittiğini düşünmek ve neden böyle bir durum yarattığını anlamak faydalıdır.

Tüm etkinliklerin kaynağı window olduğu için bu snippet'te, click, keydown, mousedown, contextmenu ve mousewheel etkinliklerinin hepsi, onları dinliyor olabilecek öğelere ulaşmadan durur, sona erer. Ayrıca, bundan sonra dokümana bağlanan işleyicilerin de engellenmesi için stopImmediatePropagation çağrısında bulunuruz.

stopPropagation() ve stopImmediatePropagation() öğelerinin (en azından çoğunlukla değil) sayfayı işe yaramaz hale getirmediğini unutmayın. Yalnızca etkinliklerin normalde gidecekleri yere ulaşmasını önlerler.

Ancak preventDefault() adını verdiğimiz bu işlem, varsayılan işlemi engellediğini de hatırlarsınız. Böylece, varsayılan işlemlerin (ör. fare tekerleğiyle kaydırma, klavyeyle kaydırma veya vurgulama ya da sekme tuşuyla kullanma, bağlantı tıklama, içerik menüsü görüntüleme vb.) tümü engellenir ve böylece sayfa oldukça yararsız bir durumda kalır.

Canlı demolar

Bu makaledeki tüm örnekleri tekrar tek bir yerden keşfetmek için aşağıdaki yerleştirilmiş demoya göz atın.

Teşekkür

Tom Wilson'ın Unsplash'teki lokomotif resmi.