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 önceparentElemenodeekler.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ındanodeile birlikteoldChildi 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 stringlerenode(düÄüm) ekler,node.prepend(...nodes or strings)â düÄüm veya düÄüm baÅındaki stringlerenode(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,nodeile 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:
<p>Hello</p>
<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,htmlekler,"afterbegin"â baÅındaelemehtmlekler,"beforeend"â sonundaelemehtml" ekler,"afterend"âelemden hemen sonra,htmlekler.
İ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)parentElemdennodeı 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Äerdeep==truetü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 öncehtmlekler,"afterbegin"â baÅindaelemehtmlekler,"beforeend"â sonundaelemehtmlekler,"afterend"âelemden hemen sonrahtmlekler.
Ayrıca benzer yöntemler
elem.insertAdjacentTextveelem.insertAdjacentElementvardı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
Yorumlar
<code>kullanınız, birkaç satır eklemek için ise<pre>kullanın. EÄer 10 satırdan fazla kod ekleyecekseniz plnkr kullanabilirsiniz)