JavaScript Temelleri

Bölüm 20

Uygulamalar

Bölüm 20 Sayfa 2

20.2 -Sayfa Yapısını Değiştirmeyen Uygulamalar

Bu uygulamalar sayfanın (X)HTML ve CSS kodlarınının çözümlenmesiden oluşan sayfanın düğüm sayısını değiştirmez, fakat bu kodların incelenmesi ile çeşitli sonuçların elde edilmesini sağlar. Bu konuda bazı örnekler aşağıda görülmektedir.

20.2.1 - Bir Sayfanın Toplam Düğüm Sayısı

W3C-DOM sayfayı birbirleri ile hiyerarşik ilişkileri olan, düğüm noktaları (nodal noktalar) olarak kabul eder. Bu düğüm noktaları sadece (X)HTML elementlerinden oluşmazlar, bunların yanında değişik sayfa öğeleri de düğüm noktaları olarak kabul edilirler.

Belge yapılanması belge çözümleyicine göre değişir. Bu nedenle, her belge çözümleyicisi, bir düğüm için farklı sayılarda alt düğüm yapılandırabilir. Aynı şekilde, alt düğümler dizisinde düğümlerin sıralanması da belge çözümleyiciden belge çözümleyiciye değişebilir. Bu nedenle düğümlere erişim için, id niteliği gibi sabit röper noktalarından yararlanmak gerekir.

Yukarıdaki şemanın uygulamada gerçekleşen şeklinin sınanması için, aşağıda görülmekte olan örnek bir sayfa kodlarının değişik belge çözümleyiciler tarafından nasıl farklı düğüm yapıları ile yapılandırıldığını inceleyelim.

<?xml version="1.0" encoding="windows-1254" ?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xtml11.dtd">
<html xmlns="http://www.w3.org/1999/06/xhtml" xml:lang="tr"

<head>
<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=windows-1254" />
<meta http-equiv="Content-Language" content="tr" />
<meta http-equiv="Content-Style-Type" content="text/css" />
<meta http-equiv="Content-Script-Type" content="text/JavaScript" />
<meta name="Title"  content="Webtech JavaScript Turkish Tutorial" />
<meta name="Subject" content="JavaScript Turkish Tutorial" />
<meta name="Description" content="JavaScript Tutorial in Turkish Language" />
<meta name="Keywords" content="JavaScript Tutorial Turkish" />
<meta name="Language" content="tr" />
<meta name="Abstract" content="JavaScript Turkish Tutorial" />
<meta name="Publisher" content="Prof. Dr. Bedri Doğan Emir" />
<meta name="Distribution" content="Local" />
<meta name="Robots" content="Index" />
<link rel="stylesheet" type="text/css" href="../css/JSstyle.css" />
<title>20.2.3-uyg-1</title>
</head>
<body>
<table class="layout-top"summary="Başlık">
<tr>
<td><img src="../images/banner.gif" alt="Banner" class="banner"/></td>
<td class="top1text">JavaScript Temelleri - Uygulamalar -</td>
<td class="top1previous"><a href ="../b20/b20s4.htm#b20.2.1-uyg-1"><img 
src="../images/previous.gif" alt="önceki" /></a></td>
</tr>
<tr>
<td></td>
<td class="top2text">b20.2.1-uyg-1.htm</td>
<td class="top2previous">Konu Sayfasına Dönüş</td>
</tr>
<tr>
<td></td>
<td class="top3text">Bir Belgenin Yapısal Kodlarının Çözümlenmesinde Toplam Düğüm Sayısı </td>
<td></td>
</tr>
</table>

<ul id="topnavlist1">
<li id="ilk">
<a href="./b20.2.1-uyg-1-src.htm"><em>Sayfanın XHTML Kaynak Kodları</em></a>
</li>
<li id="atla1"></li>
<li id="orta">
<a href="./JSstyle-css.htm"><em>Sayfanın CSS Stil Kodları</em></a>
</li>

<li id="atla2"></li>
<li id="son">
<a href="./b20.2.1-uyg-1-js.htm"><em>Sayfanın JavaScript Program Kodları</em></a>
</li>
<li id="topnavlist1-sonlama"></li>
</ul>

<p class="indent"  id="yazım">
 </p>

<p class="indent">
<span class=red"><em>Bu sayfanın toplam <b>düğüm sayısı<b>,</em></span>
<span class="blue"><em>yukarıda <b>görülmektedirı<b>.</em></span>
 </p>

<ul id="navbottom">
<li id="index">
<a href="../index.htm"><em> &laquo; İndeks </em></a>
</li>
<li id="denge"></li>
<li id="sayfa">
<a href="../b20/b20s4.htm#b20.2.1-uyg-1"><em> Konu Sayfasına Dönüş &raquo; </em></a>
</li>
<li id="navbottom-sonlama"></li>
</ul>
<--Script Yükleme Alanı -->
<script type="text/javascript" src="../js/b20.2.1-uyg-1.js">
</script>
<--Script Yükleme Alanı Sonu-->
</body>
</html>
		

Bu belgenin MS IE 8 ve Opera 10 ile çözümlenmesinden sonra, document düğümünün, alt düğümlerinin sayıları ve özellikleri karşılaştrıldığında, aşağıdaki sonuçlar alınır.

Tablo : 20.2.1 - 1: document Düğümünün MS IE 8 de ve Opera 10 da Alt Düğüm Sayıları ve Alt Düğümlerin Özellikleri
Alt Düğüm MS IE 8 Opera 10
Toplam Alt Düğüm Sayısı 2 3
altDüğüm[0].nodeName #comment xml
altDüğüm[0].nodeType 8 7
altDüğüm[0].nodeValue Doctype... version 1.0 ...
altDüğüm[1].nodeName HTML html
altDüğüm[1].nodeType 1 10
altDüğüm[1].nodeValue null null
altDüğüm[2].nodeName - HTML
altDüğüm[2].nodeType - 1
altDüğüm[2].nodeValue - null

Yukarıdaki sonuçlar, bize her iki belge çözümleyicilesinin kodları çözümlerken farklı düzenlemelerde hiyerarşik düğüm yapıları yarattığını ortaya koymaktadır. Belge kökü document nesnesinin alt düğüm sayısı MS IE8 de 2, Opera 10 da ise 3 tanedir. Bu alt nesnelerin tip sralanma ve değerleri de her iki belge çözümleyicide farklıdır.

Aynı sayfa kodlarının, MS IE8 ve 2, Opera 10 da çözümlenmesinde, html düğümünün her iki belge çözümleyicide de aynı yapıda olduğu görülmektedir.

Tablo : 20.2.3 - 2 : html Düğümünün MS IE 8 de ve Opera 10 da Alt Düğüm Sayıları ve Alt Düğümlerin Özellikleri
Alt Düğüm MS IE 8 Opera 10
Toplam Alt Düğüm Sayısı 2 2
altDüğüm[0].nodeName HEAD HEAD
altDüğüm[0].nodeType 1 1
altDüğüm[0].nodeValue null null
altDüğüm[1].nodeName BODY BODY
altDüğüm[1].nodeType 1 1
altDüğüm[1].nodeValue null null

Aynı sayfa kodlarının, MS IE8 ve 2, Opera 10 da çözümlenmelerinin karşılaştırılmasına head düğümü ile devam edildildiğinde eşitliğin bozulduğu ve her iki belge çözümleyicide farrklı sayıda alt düğüm yaratılmış olduğu görülür. Bu element düğümünün MS IE 8 de alt düğüm sayısı 16 iken, Opera 10 da 33 tane alt düğüm oluşmuştur.

Bu durumda, tekrar edelim, belge kodlarının çözümlenmesi sonunda, farklı belge çözümleyiciler farklı belge yapıları oluştururlar. Yukarıdaki incelemelerden de görülmüş olduğu gibi, bu yapıların düğüm ve alt düğüm yapılanmalarında, düğümlerin sayıları ve sıralanmaları farklı olabilir. Bu durumda değişik belge çözümleyicilerde çözümlenmiş belgelerin içinde dolaşımda, aynı düğüme ulaşılmasında, değişmeyen ve tüm belgede bir tane olması gereken, id nitelik değerlerinden yararlanılması gerekir.

Yukarıdaki bilgilerden, bir belgede toplam düğüm sayısının saptanmasında, sadece ilk alt düğümlerin sayılmasının yeterli olamayacağını ortaya koymaktadır. Örnek olarak document düğümünün MS IE 8 de sadece 2 tane alt düğümü vardır. Sadece ilk düzey alt düğümlerle yetinilirse, tüm belgede sadece 3 tane düğüm olduğu şeklinde yanlış bir sonuca ulaşılır. Oysa ki , alt düğümlerden biri olan html düğümünün de iki alt düğümü bulunmakta ayrıca , bunlardan, head düğümünün MS IE 8 de 16 tane alt düğümü bulunmaktadır. Yani, bir belgenin toplam düğüm sayısı veya bir düğümün toplam alt düğümlerinin sayısı, ancak her alt düğümün de alt düğümlerinin sayısının saptanması ile ortaya çıkabilir.

Bir belgenin toplam düğüm sayısı, farklı belge çözümleyicilerde çözümlenmiş belgelerde farklı sayılar olacaktır. Bu sayının saptanması için David Flanagan JavaScript The Definitive Guide kitabının 17.1 konusunda, rekürsive fonksiyonlardan yararlanılması yolunu göstermiş ve örnek bir uygulama yapmıştır. Aynı yöntemi kullanan bir program metni aşağıda görülmekte ve bu program ilişkli olduğu uygulama sayfasında çalışmaktadır. Bu programın farklı belge çözümleyicilerde çalıştırılarak sonuçların karşılaştırılması deneyim sağlayıcı olacaktır.

/* <![CDATA[  */

function elementdüğümüSay(n) {  // n bir düğüm olmalıdır !
var
sayı = 0,
altSoy = n.childNodes; // tüm alt düğümler koleksiyonu atandı !

sayı++;

for (var i = 0; i < altSoy.length; i++) {
sayı = sayı + düğümSay(altSoy.item(i)); // rekürsiyon !
}

return sayı; // alt düğümler dahil toplam sayı !
}
		
function düğümSay() {
var düğüm = document,
sayı = 0,
altDüğümler = düğüm.childNodes;

sayı ++;// düğümün kendisi sayılıyor !

for (var i = 0; i < l < altDüğümler.length; i++ ) {
sayı = sayı + düğümSay(altSoy.item(i));//ilk alt düzey düğümler ve onların alt düzey düğümleri sayılıyor !
}

bilgiYaz('Bu Belgedeki Toplam Düğüm Sayısı  = ', sayı, 'yazım');
}

sayfaYüklenmesiTamamlandıktanSonraÇalıştır(toplamDüğümSayısı);
			
		/* ]]>  */
		

Yukardıdaki programın çalıştığı sayfada MS IE 8 in saptadığı toplam düğüm sayısı 85, Opera 10 nun saptadığı toplam düğüm sayısı 167, WebKit Temelli Safari 4.0.3, Google Chrome 4 ve Google Chrome Plus 1.5 ün saptadığı toplam düğüm sayısı 181 olmaktadır.

Bir çözümlenmiş web sayfasının kodlarında ne kadar düğüm oluştuğu kullanıcının kontrolü ve bir noktada ilgisinin dışındadır. Kullanıcılar element düğümleri ile daha çok ilgilidir. Çünkü element düğümleri JavaScript program adımları ile sayfaya eklenebilir, içeriği ve nitelikleri değiştirilebilir. Ayrıca, bir web sayfasındaki toplam element düğümü sayısı tüm belge çözümleyicilerde aynıdır.

20.2.2 - Bir Düğümün Alt Düğümleri Arasında Bulunan Element Düğümleri Sayısı

Bir web sayfasındaki toplam element düğümleri sayısı, bir önceki programa, bulunan düğümlerin eğer element düğümleri ise sayılmasını sağlayan filtreler eklenerek salt element düğümlerini sayar hale getirilebilir. Bu programın kodları aşağıda görülmekte ve bu program, bağlantılı olduğu uygulama sayfasında çalışmaktadır.

/* <![CDATA[  */

function elementDüğümüSay(n) {  // n bir düğüm olmalıdır !
var
sayı = 0,
altSoy = {};


if (n.nodeType === 1) { // eğer n bir Element düğümü ise ....
altSoy = n.childNodes; // tüm alt düğümler koleksiyonu atanır.
}

if (n.nodeType === 1) { // eğer n bir Element düğümü ise ....

sayı++; // sayacı 1 arttır !
}

for (var i = 0; i < altSoy.length; i++) {// tüm element tipi alt düğümler için...
sayı = sayı +elementDüğümüSay(altSoy.item(i)); // tüm element tipi alt düğümlerin kendi alt düğümlerinin de sayılabilmesı için, rekürsiyon çağrısı !
}

return sayı; // n düğümünün tüm alt element düğümleri sayısı !
}
		
function toplamElementDüğümüSayısı() {
var düğüm = document,
sayı = 0,
altDüğümler = {};

if (düğüm.nodeType === 1 || düğüm.nodeType === 9) { // eğer n bir element veya document düğümü ise ....}

altDüğümler = düğüm.childNodes;


for (var i = 0; i < l < altDüğümler.length; i++ ) {
sayı = sayı + düğümSay(altDüğümler.item(i));//ilk alt düzey düğümler ve kendi alt düzey düğümleri sayılıyor !
}

bilgiYaz('Element Düğümlerinin Toplam Sayısı (Çocuklar ve Torunlar)  = ', sayı, 'yazım');
}

sayfaYüklenmesiTamamlandıktanSonraÇalıştır(toplamElementDüğümüSayısı);
			
		/* ]]>  */
		

Yukarıda kodları görülen JavaScript programı, bir sayfanın düğüm noktalarının türlerini taramakta ve eğer bunlar arasında element düğümü türü bulunuyorsa kümülatif element sayısını bir arttırmakta ve tarama sonunda incelenen belgenin toplam element düğümü sayısı saptanmaktadır. Bu programın çalıştığı uygulama sayfasında toplam 65 tane element düğümünün bulunduğu görülmektedir.

Bazı durumlarda, bir element düğümünün sadece ilk düzey (çocuk) element düğümleri ile ilgilenilir. Bu bilgi için aşağıda kodları görülen JavaScript programı kullanılabilir. Bu program ilişik olduğu uygulama sayfasında çalışmaktadır.

/* <![CDATA[  */

function ilkAltDüzeyElementDüğümüSayısı() {
var düğüm = document.getElementsByTagName('html').item(0),
sayı = 0,
altDüğümler = {};

if (düğüm.nodeType === 1 || düğüm.nodeType === 9) { // eğer n bir element veya document düğümü ise ....}

altDüğümler = düğüm.childNodes;// tüm alt düğümler saptanıyor !
			
for (var i = 0; i < l < altDüğümler.length; i++ ) {
			
if (altDüğümler.item(i).nodeType === 1) {// eğer alt element düğümü bir Element düğümü ise ....

sayı ++;// alt element düğümü sayılıyor !
}
}
}

bilgiYaz('İlk Alt Düzey Element Düğümlerinin Sayısı (Çocuklar)  = ', sayı, 'yazım');
}

sayfaYüklenmesiTamamlandıktanSonraÇalıştır(ilkAltDüzeyElementDüğümüSayısı);
			
		/* ]]>  */
		

Yukarıdaki JavaScript programı ile <html> elementinin alt Element düğümlerinin toplam olarak iki tane olduğu anlaşılmaktadır. Bunlardan birinin <head> diğerinin de, <body> elementi olması gerektiği anlaşılabilir.

20.2.3 - DOM Yüklemesini Gözleyen Script

Rollover etkisi olmayan resim galerisi gibi birçok sayfada resimlerin indirilmesi çok süre alabilir. JavaScript programlarının başlaması için ise, resimler dahil tüm sayfanın yüklenmesi değil, sadece DOM öğelerinin yüklenmesi yeterlidir. Aşağıdaki kodları, brodercake önermiştir. Bu programın yazılımı aşağıda görülmektedir :

/* <![CDATA[  */

function globalYap () {
window.global = 1.64e-3;
}

function globalOku () {
var x = global * 2;

sonuçYaz('x = ', x, 'yazımYeri');
}



// *****************************************************
// DOM scripting by brothercake -- http://www.brothercake.com/
// GNU Lesser General Public License -- http://www.gnu.org/licenses/lgpl.html
//******************************************************



//DOM-ready watcher
function domReady()
{
	//start or increment the counter
	this.n = typeof this.n == 'undefined' ? 0 : this.n + 1;
	
	//if DOM methods are supported, and the body element exists
	//(using a double-check including document.body, for the benefit of older moz builds [eg ns7.1] 
	//in which getElementsByTagName('body')[0] is undefined, unless this script is in the body section)
	//and any elements the script is going to manipulate exist
	if
	(
		typeof document.getElementsByTagName != 'undefined' 
		&& (document.getElementsByTagName('body')[0] != null || document.body != null)
		//&& document.getElementById('something') != null 
	)
	{
	//-- DOM SCRIPTING GOES HERE --
	
	globalYap();
	globalOku();


	//-----------------------------
	}

	//otherwise if we haven't reached 60 (so timeout after 15 seconds)
	//in practise, I've never seen this take longer than 7 iterations [in kde 3.2.2 
	//in second place was IE6, which takes 2 or 3 iterations roughly 5% of the time]
	else if(this.n < 60)
	{
		//restart the watcher
		//using the syntax ('domReady()', n) rather than (domReady, n)
		//because the latter doesn't work in Safari 1.0
		setTimeout('domReady()', 250);
	}
};
//start the watcher
domReady();

/* ]]>  */
		

Yukarıdaki program, fazla resim içeren sitelerde yararlı olabilir. Fazla resim içermeyen siteler için, klasik window.onload fonksiyonu yeterlidir.

Bu programda uygulanan global değişkenlerin bir fonksiyon içine alınması düşüncesi, Jeremy Keith tarafından düşünülmüştür. Bu şekilde, global değişken kullanımın sakıncalarının azaltaılması hedeflenmektedir. Yine de, kesinlikle gereksinme olmadıkça global değişkenlerin kullanılmaması programcılık açısından en uygun yol olacaktır.