24 Ocak 2022

Modifying the document

DOM değişiklikleri “canlı” sayfalar oluşturmak için anahtardır.

Burada, “anında” nasıl yeni öğeler yaratmayı ve var olan sayfa içeriğini değiştirmeyi göreceğiz.

İlk önce, basit bir örnek göreceğiz ve ondan sonra yöntemleri açıklacağız.

Example: show a message

Başlangıç için, sayfa üzerinde alertten daha güzel görünen bir mesajın nasıl eklendiğini görelim.

İşte nasıl görüneceği:

<style>
.alert {
  padding: 15px;
  border: 1px solid #d6e9c6;
  border-radius: 4px;
  color: #3c763d;
  background-color: #dff0d8;
}
</style>

<div class="alert">
  <strong>Hi there!</strong>You've read an important message.
</div>

Bu bir HTML örneğidir. Şimdi aynı divi JavaScript ile oluşturalım (farzedelim ki, styles(strong kelimesine referans) hala HTML içinde veya bir dışsal CSS dosyasıdır).

Creating an element

DOM düğümleri(nodes) oluşturmak icin iki yöntem vardır:

document.createElement(tag)

Verilen etiketle birlikte yeni bir element düğümü(element node) oluşturur:

let div = document.createElement('div');
document.createTextNode(text)

Verilen metinle yeni bir metin düğümü(text node) oluşturur:

let textNode = document.createTextNode('Here I am');

Creating the message

Bizim durumumuzda, verilen sınıflarla ve içindeki mesajla bir “div” yapmak istiyoruz:

let div = document.createElement('div');
div.className = "alert alert-success";
div.innerHTML = "<strong>Merhaba</strong> Onemli bir mesaj okudunuz.";

Bundan sonra, DOM elementimiz hazırdır. Şu anda, o sadece bir değişkendir ve onu göremeyiz. Bunun sebebi, o henüz sayfanın içine işlenmemiştir.

Insertion methods

Divi göstermek için, onu document içinde bir yere eklememiz gerekir. Örneğin, document.body içinde.

Bunun için özel bir yöntem appendChild vardır: document.body.appendChild(div).

İste tam kod:

<style>
.alert {
  padding: 15px;
  border: 1px solid #d6e9c6;
  border-radius: 4px;
  color: #3c763d;
  background-color: #dff0d8;
}
</style>

<script>
  let div = document.createElement('div');
  div.className = "alert alert-success";
  div.innerHTML = "<strong>Hi there</strong>You've read an important message.";

  document.body.appendChild(div);
</script>

Burada, bir üst öğeye(parent element) düğüm(node) eklemek için kullanılan yöntemlerin kısa bir listesi (kısaca parentElem):

parentElem.appendChild(node)

parentElemin son öğesi(last child) olarak 'node’ı ekler.

Asagidaki örnek, <ol>un sonuna yeni bir <li> ekler:

<ol id="list">
  <li>0</li>
  <li>1</li>
  <li>2</li>
</ol>

<script>
  let newLi = document.createElement('li');
  newLi.innerHTML = 'Hello, world!';

  list.appendChild(newLi);
</script>
parentElem.insertBefore(node, nextSibling)

nextSiblingden önce parentEleme node ekler.

Aşağıdakı kod, ikinci <li>den önce yeni bir liste ekler:

<ol id="list">
  <li>0</li>
  <li>1</li>
  <li>2</li>
</ol>
<script>
  let newLi = document.createElement('li');
  newLi.innerHTML = 'Hello, world!';

  list.insertBefore(newLi, list.children[1]);
</script>

newLiyi ilk oğe olarak eklemek icin, bunu şöyle yapabiliriz:

list.insertBefore(newLi, list.firstChild);
parentElem.replaceChild(node, oldChild)

parentElemin alt öğeleri arasında node ile birlikte oldChildi yenisiyle yer degistirir.

Tüm bu yöntemler eklenen düğümü geri döndürür. Diğer anlatımla,parentElem.appendChild(node) nodei geri döndürür.Ama genellikle geri döndürülen değer kullanılmaz, sadece yöntemi çalıştırırız.

Bu yöntemler “eskimiştir”: eski zamanlardan beri varlar ve onlarla birçok eski scriptlerde karsılasabiliriz. Ne yazık ki, bunlar yeterince esnek değillerdir.

Örneğin, bir string olarak varsa html nasıl eklenir? Ya da, verilen bir düğüm, üst öğeye(parent) başvurmadan nasıl kaldırılır? Elbette ki, bu yapılabilinir, ama zarif bir şekilde değil.

Bu yüzden, tüm durumları kolayca idare etmek için iki ekleme yöntemi daha vardır.

prepend/append/before/after

Bu yöntemler kümesi daha esnek eklemeler sunar.

  • node.append(...nodes or strings) – düğümün sonuna veya düğümlerin sonundaki stringlere node(düğüm) ekler,
  • node.prepend(...nodes or strings) – düğüm veya düğüm başındaki stringlere node(düğüm) ekler,
  • node.before(...nodes or strings) –- node(düğüm)'den önce düğümler veya stringler ekler,
  • node.after(...nodes or strings) –- node(düğüm)'den sonra düğümler veya stringlere ekler,
  • node.replaceWith(...nodes or strings) –- verilen düğümler veya stringler, node ile yer değistirir.

Bunlarin hepsi DOM düğümler ve/veya stringlerinin bir listesini kabul eder. Eğer bir string verilirse, metin düğümü(text node) olarak eklenir.

İşte bir listeye daha fazla madde(item) ve onun öncesinde/sonrasında metin eklemek için bu yöntemleri kullanmanın bir örneği:

<ol id="ol">
  <li>0</li>
  <li>1</li>
  <li>2</li>
</ol>

<script>
  ol.before('before');
  ol.after('after');

  let prepend = document.createElement('li');
  prepend.innerHTML = 'prepend';
  ol.prepend(prepend);

  let append = document.createElement('li');
  append.innerHTML = 'append';
  ol.append(append);
</script>

İşte yöntemlerin ne yaptığına dair küçük bir resim:

Öyleyse son liste şöyle olacak:

before
<ol id="ol">
  <li>prepend</li>
  <li>0</li>
  <li>1</li>
  <li>2</li>
  <li>append</li>
</ol>
after

Bu yöntemler, tek bir çağrıda çoklu düğümler ve metin parçalarının listesi ekleyebilir.

Örneğin, buraya bir string ve bir element eklenir:

<div id="div"></div>
<script>
  div.before('<p>Hello</p>', document.createElement('hr'));
</script>

Tüm metinler metin olarak eklenir.

Öyleyse son HTML:

&lt;p&gt;Hello&lt;/p&gt;
<hr>
<div id="div"></div>

Diğer bir deyişle, stringler elem.textContentin yaptığı gibi güvenli bir şekilde eklenir.

Böylece, bu yöntemler sadece DOM düğümleri veya metin parçaları eklemek için kullanılabilinir.

Ama HTML’yi “html olarak”, eklemek istersek, tüm etiketler(tags) ve elementlerle elem.innerHTML gibi çalışıyorsa?

insertAdjacentHTML/Text/Element

Başka, oldukça çok yönlü bir yöntem var: elem.insertAdjacentHTML(where, html).

İlk parametre, “elem” e göre nereye ekleneceğini belirleyen bir kod kelimesidir. Aşağıdakilerden biri olmalıdır:

  • "beforebegin"elemden hemen önce, html ekler,
  • "afterbegin" – başında eleme html ekler,
  • "beforeend" – sonunda eleme html" ekler,
  • "afterend"elemden hemen sonra, html ekler.

İkinci parametre “HTML olarak” eklenmiş bir HTML dizisi(string)dir, .

Örneğin:

<div id="div"></div>
<script>
  div.insertAdjacentHTML('beforebegin', '<p>Hello</p>');
  div.insertAdjacentHTML('afterend', '<p>Bye</p>');
</script>

…Şuna yönlendirir:

<p>Hello</p>
<div id="div"></div>
<p>Bye</p>

Bu şekilde sayfamıza isteğe bağlı bir HTML ekleyebiliriz.

İşte ekleme türevlerinin resmi:

Bu ve önceki resim arasındaki benzerlikleri kolayca fark edebiliriz. Ekleme noktaları aslında aynıdır, ancak bu yöntem HTML ekler.

Yöntemin iki kardeşi vardır:

  • elem.insertAdjacentText(where, text) – ayn sözdizimi(syntax), ama bir “metin” dizesi HTML yerine “metin olarak” eklenir,
  • elem.insertAdjacentElement(where, elem) – ayni sözdizimi(syntax), ama bir oge ekler,

Esas olarak sözdizimini(syntax) “düzgün” yapmak için vardırlar. Uygulamada, çoğu zaman yalnızca “insertAdjacentHTML” kullanılır. Çünkü öğeler ve metin için append/prepend/before/after yöntemlerimiz var – Onlari yazmak daha kısadır ve düğüm/metin parçası ekleyebilirler.

İşte size bir mesaj göstermenin alternatif bir çeşidi:

<style>
.alert {
  padding: 15px;
  border: 1px solid #d6e9c6;
  border-radius: 4px;
  color: #3c763d;
  background-color: #dff0d8;
}
</style>

<script>
  document.body.insertAdjacentHTML("afterbegin", `<div class="alert alert-success">
    <strong>Hi there!</strong> You've read an important message.
  </div>`);
</script>

Cloning nodes: cloneNode

Benzer bir mesaj daha nasıl eklenir?

Bir işlev(function) yapabilir ve kodu oraya koyabiliriz. Ama alternatif yol, var olan divi klonlamak ve içindeki metni degistirmek olacaktır (eğer gerekliyse).

Bazen büyük bir unsurumuz olduğunda, bu daha hızlı ve daha basit olabilir.

-Çağrı elem.cloneNode(true) öğenin “derin” bir klonunu oluşturur – tüm nitelikler ve alt(child) elementler ile… Eğer elem.cloneNode(false)i çağırırsak, daha sonra klon alt(child) elementler olmadan yapılır.

Mesaji kopyalamanın bir örneği:

<style>
.alert {
  padding: 15px;
  border: 1px solid #d6e9c6;
  border-radius: 4px;
  color: #3c763d;
  background-color: #dff0d8;
}
</style>

<div class="alert" id="div">
  <strong>Hi there!</strong>You've read an important message.
</div>

<script>
  let div2 = div.cloneNode(true); // mesaji kopyala
  div2.querySelector('strong').innerHTML = 'Bye there!'; // kopyayı değiştir

  div.after(div2); // varolan div'den sonra kopyayı göster
</script>

DocumentFragment

DocumentFragment düğüm listelerini geçirmek için bir sarıcı olarak görevi olan özel bir DOM düğümüdür.

Buna diğer düğümler ekleyebiliriz, ama bunu herhangi bir yere yerleştirdiğimizde, daha sonra içeriği bunun yerine eklenir.

Örneğin, aşağıdaki getListContent <li> öğeleriyle bir parça oluşturur, ki daha sonra <ul>içine eklenir:

<ul id="ul"></ul>

<script>
function getListContent() {
  let fragment = new DocumentFragment();

  for(let i=1; i<=3; i++) {
    let li = document.createElement('li');
    li.append(i);
    fragment.append(li);
  }

  return fragment;
}

ul.append(getListContent()); // (*)
</script>

Lütfen not edin, sondaki satıra (*), DocumentFragmenti ekleriz, ama o “içine karışır”, sonuçta ortaya çıkan yapı:

<ul>
  <li>1</li>
  <li>2</li>
  <li>3</li>
</ul>

‘DocumentFragment’ pek nadir açıkça kullanılır. Bunun yerine bir sıra düğümü geri döndürebiliyorsak, neden özel bir düğüme eklemeliyiz? Yeniden yazılmış örnek:

<ul id="ul"></ul>

<script>
function getListContent() {
  let result = [];

  for(let i=1; i<=3; i++) {
    let li = document.createElement('li');
    li.append(i);
    result.push(li);
  }

  return result;
}

ul.append(...getListContent()); // append + "..." operator = friends!
</script>

Temel olarak DocumentFragment ifadesinden bahsediyoruz. çünkü bunun üzerinde template element, gibi bazı kavramlar vardır, ki daha sonra bunlari ele alacağız.

Removal methods

Düğümleri kaldırmak için, aşağıdaki yöntemler vardır:

parentElem.removeChild(node)
parentElemden nodeı kaldırır (Farzedelim ki, o bir alt öğedir(child)).
node.remove()
nodeı kendi yerinden kaldırır.

Kolayca görebiliriz ki, ikinci yöntem çok daha kısadır. İlki tarihsel nedenlerden dolayı vardır.

Eğer biz bir öğeyi baska bir yere *taşımak* istiyorsak --- Onu eskisinden kaldırmaya gerek yok.

**Tüm ekleme yöntemleri düğümü otomatik olarak eski yerinden kaldırır.**

 Örneğin, elementleri değiştirelim:

```html run height=50
<div id="first">First</div>
<div id="second">Second</div>
<script>
  // remove'i cağırmaya gerek yok
  second.after(first); // #second'i al ve ondan sonra - #first'i ekle 
</script>
```

Mesajımız bir saniye sonra ortadan kaybolsun:

<style>
.alert {
  padding: 15px;
  border: 1px solid #d6e9c6;
  border-radius: 4px;
  color: #3c763d;
  background-color: #dff0d8;
}
</style>

<script>
  let div = document.createElement('div');
  div.className = "alert alert-success";
  div.innerHTML = "<strong>Hi there!</strong> You've read an important message.";

  document.body.append(div);
  setTimeout(() => div.remove(), 1000);
  // or setTimeout(() => document.body.removeChild(div), 1000);
</script>

A word about “document.write”

Bir web sayfasına bir şey eklemenin çok eski bir yöntemi daha var: document.write.

Sözdizimi(Syntax):

<p>Somewhere in the page...</p>
<script>
  document.write('<b>Hello from JS</b>');
</script>
<p>The end</p>

document.write(html) çağrısı “burada ve şimdi” sayfasına ‘html’ yazar. html string dinamik olarak oluşturulmus olabilir, bu nedenle esnektir. Tam teşekküllü bir web sayfası oluşturmak ve yazmak için JavaScript kullanabiliriz.

Yöntem DOM’un, standartların olmadığı zamanlardan geliyor… Gerçekten eski zamanlar. O hala yaşıyor, çünkü onu kullanan scriptler vardır.

Modern scriptlerde, onu pek nadir görebiliriz, çünkü aşağıdaki önemli sınırlama nedeniyle:

“document.write” çağrısı yalnızca sayfa yüklenirken yapılır

Eğer onu daha sonra çağırırsak, var olan belge içeriği silinmiş olur.

Örneğin:

<p>Bir saniye sonra bu sayfanın içeriği değiştirilmiş olacak...</p>
<script>
  // document.write after 1 second
  // that's after the page loaded, so it erases the existing content
  setTimeout(() => document.write('<b>...By this.</b>'), 1000);
</script>

Öyleyse, yukarıda bahsettiğimiz diğer DOM yöntemlerinin aksine, “yüklendikten sonra” aşamasında kullanılamaz olur.

Bu olumsuz tarafıydı.

Teknik olarak, internet tarayıcı gelen HTML’yi okurken, (“parsing/ayrıştırma”) document.write çağrılır ve bir şey yazar, tarayıcı HTML metninde ilk başta olduğu gibi onu işler.

Ki bize olumlu tarafı verir – o çok hızlı çalışır, çünkü DOM değişikligi yoktur. DOM henüz oluşturulmamışken, onu doğrudan sayfadaki metne yazar, ve internet tarayıcı oluşum-süresinde onu DOM’a yerleştirir.

Öyleyse, HTML’ye dinamik olarak çok fazla metin eklememiz gerekirse ve biz sayfa yükleme aşamasındayız ve hız önemlidir, bu yardım edebilir. Ama uygulamada bu gereksinimler pek nadir bir araya gelir. Ve genellikle biz bu yöntemi sadece eski olan scriptlerde görebiliriz.

Summary

Yeni düğümler yaratma yöntemleri:

  • document.createElement(tag) – verilen etiketle(tag) bir element yaratır,
  • document.createTextNode(value) – bir metin düğümü(text node) yaratır (pek nadir kullanılır),
  • elem.cloneNode(deep) – elementi kopyalar, eğer deep==true tüm alt içerikleriyle ise.

-Düğümlerin yerleştirilmesi ve çıkarılması:

– En üst ogeden(parent):

  • parent.appendChild(node)
  • parent.insertBefore(node, nextSibling)
  • parent.removeChild(node)
  • parent.replaceChild(newElem, node)

Tüm bu yöntemler nodeı geri dönderir.

  • Düğümler ve komut dosyalarinin verilmis bir listesi:

    • node.append(...nodes or strings) – sonunda ‘düğüme’ ekler,
    • node.prepend(...nodes or strings) – başında “düğüme” ekler,
    • node.before(...nodes or strings) –- düğümden hemen önce ekler,
    • node.after(...nodes or strings) –- düğümden hemen sonra ekler,
    • node.replaceWith(...nodes or strings) –- “düğümü” değiştir.
    • node.remove() –- “düğümü” kaldırır.

    Metin stringler “metin olarak” eklenir.

  • Bir parca verilen HTML: elem.insertAdjacentHTML(where, html), nereye bağlı olduğuna dair ekleme yapar:

    • "beforebegin"elemden hemen önce html ekler,
    • "afterbegin" – başinda eleme html ekler,
    • "beforeend" – sonunda eleme html ekler,
    • "afterend"elemden hemen sonra html ekler.

    Ayrıca benzer yöntemler elem.insertAdjacentText ve elem.insertAdjacentElement vardır, onlar metin stringler ve elementler ekler, ama pek nadir kullanılır.

  • Yükleme tamamlanmadan önce HTML’yi sayfaya eklemek için:

    • document.write(html)

    Sayfa yüklendikten sonra böyle bir çağrı belgeyi siler. Çoğunlukla eski scriptlerde görülür

Görevler

önem: 5

Boş bir DOM elementimiz elem ve bir string metnimiz text var.

Bu 3 komuttan hangisi tamamen aynıdır?

  1. elem.append(document.createTextNode(text))
  2. elem.innerHTML = text
  3. elem.textContent = text

Cevap: 1 ve 3.

Her iki komut da 'metin’i(text) “elem” e ‘metin olarak’ eklemeyle sonuçlanır.

İşte bir örnek:

<div id="elem1"></div>
<div id="elem2"></div>
<div id="elem3"></div>
<script>
  let text = '<b>text</b>';

  elem1.append(document.createTextNode(text));
  elem2.innerHTML = text;
  elem3.textContent = text;
</script>
önem: 5

clear(elem) adında, elementten her şeyi kaldıran bir fonksiyon yarat.

<ol id="elem">
  <li>Merhaba</li>
  <li>Dünya</li>
</ol>

<script>
  function clear(elem) { /* sizin kodunuz */ }

  clear(elem); // listeyi temizler
</script>

İlk olarak, bunun nasıl yapılmadığını görelim:

function clear(elem) {
  for (let i=0; i < elem.childNodes.length; i++) {
      elem.childNodes[i].remove();
  }
}

Bu işlemeyecektir, çünkü remove() çağrısı elem.childNodes koleksiyonunun yerini değiştirir, bu nedenle her seferinde öğeler “0” dizininden başlar. Ama “i” ıle değeri artar ve bazı öğeler atlanmış olabilir.

for..of döngüsü(loop) de aynısını yapar.

Doğru değişken(variant) şöyle olabilir:

function clear(elem) {
  while (elem.firstChild) {
    elem.firstChild.remove();
  }
}

Ve aynısını yapmanın daha basit bir yolu da var:

function clear(elem) {
  elem.innerHTML = '';
}
önem: 1

Örneği çalıstırın. Niçin table.remove(), "aaa" metnini silmez?

<table id="table">
  aaa
  <tr>
    <td>Test</td>
  </tr>
</table>

<script>
  alert(table); // tablo, olması gerektiği gibi

  table.remove();
  // niçin belgenin içinde hala 'aaa' var?
</script>

The HTML in the task is incorrect. That’s the reason of the odd thing.

The browser has to fix it automatically. But there may be no text inside the <table>: according to the spec only table-specific tags are allowed. So the browser adds "aaa" before the <table>.

Now it’s obvious that when we remove the table, it remains.

The question can be easily answered by exploring the DOM using the browser tools. It shows "aaa" before the <table>.

The HTML standard specifies in detail how to process bad HTML, and such behavior of the browser is correct.

önem: 4

Kullanıcı girdisinden bir liste oluşturmak için bir arayüz yazın.

Her liste maddesi için:

  1. ‘Komut istem’(prompt)i kullanarak bir kullanıcıya içeriği hakkında sorun. 2.Onunla <li>yi yarat ve onu <ul>ye ekle.
  2. Kullanıcı girişi iptal edene kadar devam edin (komut isteminde tuş:Esc veya CANCEL’a basarak).

Tüm elementler dinamik olarak oluşturulmalıdır.

Eğer bir kullanıcı HTML etiketleri(tags) yazıyorsa, onlara metin gibi davranılmalıdır.

Yeni pencerede göster

Please note the usage of textContent to assign the <li> content.

Çözümü korunaklı alanda aç.

önem: 5

İçiçe geçmiş nesneden, içiçe geçmiş bir ul/li listesi oluşturan bir “createTree” fonksiyonu yazın.

Örneğin:

let data = {
  "Fish": {
    "trout": {},
    "salmon": {}
  },

  "Tree": {
    "Huge": {
      "sequoia": {},
      "oak": {}
    },
    "Flowering": {
      "apple tree": {},
      "magnolia": {}
    }
  }
};

Sözdizimi (syntax):

let container = document.getElementById('container');
createTree(container, data); // creates the tree in the container

Sonuç (ağaç) şöyle görünmeli:

Bu görevi çözmenin iki yolundan birini seçin:

  1. Ağaç için HTML oluşturun ve ardından container.innerHTMLye atayın.
  2. Ağaç düğümleri (tree nodes) oluşturun ve DOM yöntemleriyle sonuna ekleyin.

Eğer her ikisini de yapabilirseniz harika olur.

Not: Ağacın yapraklar için boş <ul></ul> gibi “fazladan” öğeleri olmamalıdır.

Görevler için korunaklı alan aç.

Nesneyi gezmenin en kolay yolu özyineleme kullanmaktır.

  1. The solution with innerHTML.
  2. The solution with DOM.
önem: 5

ul/li olarak iç içe geçmiş bir ağaç var.

Her bir <li> nin neslinden gelenlerin sayısını ekleyen kodu yazın. Yaprakları geçin (çocuksuz düğümler).

Sonuç:

Görevler için korunaklı alan aç.

Metni her bir <li>nin sonuna eklemek için, metin düğümü (text node) datasını değiştiririz.

Çözümü korunaklı alanda aç.

önem: 4

Bir fonksiyon yazın: createCalendar(elem, year, month).

Çağrı, belirtilen yıl/ay için bir takvim oluşturmalıdır ve onu elem içine koymalıdır.

Takvim, bir haftanın <tr> ve bir günün <td> olduğu bir tablo olmalıdır. Üst tablo hafta içi isimleriyle <th> olmalıdır: ilk gün Pazartesi olmalı, ve Pazar gününe kadar böyle devam etmeli.

Örneğin, createCalendar(cal, 2012, 9), element calda aşağidaki takvimi oluşturmalıdır.

Not(P.S.-PostScript) Bu görev için takvimi oluşturmak yeterlidir, henüz tıklanabilir olmamalıdır.

Görevler için korunaklı alan aç.

Tabloyu bir string olarak oluşturacağız: "<table>...</table>" ve ardından innerHTML’ye atayacağız.

Algoritma:

  1. Tablo başlığını ve hafta içi gün isimlerini <th> ile oluşturun.
  2. Tarih nesnesini ile d = new Date(year, month-1) oluşturun. Bu, ayın ilk günüdür. (JavaScript’te ayların 1den değil, 0dan başladığını hesaba katarak)
  3. Ayın ilk gününe kadar ilk birkaç hücre d.getDay() boş olabilir. Onları <td></td> ile dolduralım.
  4. d: d.setDate(d.getDate()+1) içindeki günü artırın. Eğer d.getMonth() henüz gelecek ay değilse, ondan sonra takvime yeni hücre ekle. Eğer bu bir Pazar günüyse, yeni bir satır “</tr><tr>”'i ekleyin.
  5. Eğer ay bitmişse, ama tablo satırı henüz dolu değilse, onu kare yapmak için içine boş <td> ekleyin.

Çözümü korunaklı alanda aç.

önem: 4

Buradaki gibi renklendirilmiş bir saat oluşturun:

Şekillendirmek için HTML/CSS, sadece elementlerdeki zaman için Javascript kullanın.

Görevler için korunaklı alan aç.

İlk olarak, HTML/CSS yapalım.

Zamanın her bir bileşeni kendi 'span’ının içinde harika görünecektir:

<div id="clock">
  <span class="hour">hh</span>:<span class="min">mm</span>:<span class="sec">ss</span>
</div>

Ayrıca onları renklendirmek için CSS’ye ihtiyacımız olacak.

“Update” fonksiyonu, her saniye “setInterval” tarafından çağrılmak üzere saati yeniler:

function update() {
  let clock = document.getElementById('clock');
  let date = new Date(); // (*)
  let hours = date.getHours();
  if (hours < 10) hours = '0' + hours;
  clock.children[0].innerHTML = hours;

  let minutes = date.getMinutes();
  if (minutes < 10) minutes = '0' + minutes;
  clock.children[1].innerHTML = minutes;

  let seconds = date.getSeconds();
  if (seconds < 10) seconds = '0' + seconds;
  clock.children[2].innerHTML = seconds;
}

‘(*)’ Satırında, güncel tarihi kontrol ederiz. 'setInterval’a olan çağrılar güvenilir değildir: Onlar gecikmelere sebep olur.

Saat yönetimi fonksiyonları:

let timerId;

function clockStart() { // run the clock
  timerId = setInterval(update, 1000);
  update(); // (*)
}

function clockStop() {
  clearInterval(timerId);
  timerId = null;
}

Lütfen not edin ki, 'update()'e olan çağrı sadece 'clockStart()'da planlanmamıştır, ama anında ‘(*)’ satırında çalışmaya başlar. Yoksa, ziyaretçi setIntervalin ilk uygulanmasına kadar beklemek zorunda olacaktır. Ve o zamana kadar da saat boş olacaktır.

Çözümü korunaklı alanda aç.

önem: 5

Buraya iki <li> arasına <li>2</li><li>3</li> eklemek için kodu yazın:

<ul id="ul">
  <li id="one">1</li>
  <li id="two">4</li>
</ul>

When we need to insert a piece of HTML somewhere, insertAdjacentHTML is the best fit.

The solution:

one.insertAdjacentHTML('afterend', '<li>2</li><li>3</li>');
önem: 5

Bir tablo var:

İsim Soyisim Yaş
John Smith 10
Pete Brown 15
Ann Lee 5
... ... ...

Belki içinde daha çok satır var.

"name" sütunu tarafından sıralanması için kodu buraya yazın.

Görevler için korunaklı alan aç.

Çözüm kısa, ancak biraz kafa karıştırıcı görünebilir, bu yüzden burada kapsamlı yorumlar sunuyorum:

let sortedRows = Array.from(table.rows)
  .slice(1)
  .sort((rowA, rowB) => rowA.cells[0].innerHTML > rowB.cells[0].innerHTML ? 1 : -1);

table.tBodies[0].append(...sortedRows);
  1. table.querySelectorAll('tr') gibi tüm <tr>leri al, sonra onlardan bir array yap, çünkü array yöntemlerine ihtiyacımız var.

  2. İlk TR (table.rows[0]) aslında bir tablo başlığıdır, bu yüzden geri kalanını .slice(1) ile alıyoruz.

  3. Daha sonra onları ilk <td> (isim alanı)'nın içeriği ile karşılaştıryoruz.

  4. Şimdi düğümleri .append(...sortedRows) olarak doğru sırada ekleyin.

    Tabloların doğrudan belirtilmeyen bir öğesi vardır, bu yüzden onu alır ve içine ekleriz: basit bir table.append(...) başarısız olacaktır.

    Lütfen not edin: Onları kaldırmak zorunda değiliz, sadece yeniden ekle (“re-insert”), onlar eski yerlerini kendiliğinden bırakacaktır.

Çözümü korunaklı alanda aç.

Eğitim haritası