Your Ad Here

Dinamik HTML

26 Kasım 2007

CSS Stil Kullanımı

Aşağıdaki örnek programın nasıl çalıştığını görmek için Örnek-2 programını tıklayın.

<script language="javascript" type="text/javascript">
  function moveLayerLR(layerID,how){      //move layer Left or Right
      if(document.getElementById){
         document.getElementById(layerID).style.left =
             parseInt(document.getElementById(layerID).style.left) + how;
      }else if(document.all){
         document.all[layerID].style.left =
             parseInt(document.all[layerID].style.left) + how;
      }else if(document.layers){
         document.layers[layerID].left =
             parseInt(document.layers[layerID].left) + how;
      }
  }

  function moveLayerUD(layerID,how){      //move layer Up or Down
      if(document.getElementById){
         document.getElementById(layerID).style.top =
             parseInt(document.getElementById(layerID).style.top) + how;
      }else if(document.all){
         document.all[layerID].style.top =
             parseInt(document.all[layerID].style.top) + how;
      }else if(document.layers){
         document.layers[layerID].top =
             parseInt(document.layers[layerID].top) + how;
      }
  }
</script>

<div id="moveableLayer" style="position:absolute;
                               font-family:Verdana;
                               font-size:18px">
Bu hareketli katmandır!
</div>
<form>
    <div align="center">
        <table width="4%" border="0" cellspacing="4" cellpadding="0">
            <tr>
                <td align="center" width="9%">&nbsp;</td>
                <td align="center" width="57%">
                    <input type="button" value="yukarı"
                              onclick="moveLayerUD('moveableLayer',-5)">
                </td>
                <td align="center" width="34%">&nbsp;</td>
            </tr>
            <tr>
                <td align="center" width="9%">
                    <input type="button" value="sola"
                              onclick="moveLayerLR('moveableLayer',-5)">
                </td>
                <td align="center" width="57%">&nbsp;</td>
                <td align="center" width="34%">
                    <input type="button" value="sağa"
                              onclick="moveLayerLR('moveableLayer',5)">
                </td>
            </tr>
            <tr>
                <td width="9%">&nbsp;</td>
                <td align="center" width="57%">
                    <input type="button" value="aşağı"
                              onclick="moveLayerUD('moveableLayer',5)">
                </td>
                <td width="34%">&nbsp;</td>
            </tr>
        </table>
    </div>
</form>
Burada yapılan, iki tane soysal işlev yaratılmış olmasıdır. Birincisinde sağa ve sola istenilen kadar gidilmesi, diğerinde ise yukarı ve aşağıya aynı biçimde hareket edilmesi öngörülmüştür. Kısacası bu işlevleri çalıştırmak istediğinizde hareket edecek katmanın kimliğini (ID) vermek yeterli olacaktır. Bu HTML içinde işlevler çağrılırken yapılır. Kod o kadar karmaşık değildir. Daha kullanışlı kodlarla kısaltmak olanağı vardır.
Yukarıdaki soysal işlevlerden daha kısası, değişik tarayıcılarla CSS özelliklerine erişim, aşağıdaki işlevde gerçekleştirilebilir.
<script language="javascript" type="text/javascript">
      function accessCSS(layerID){
            //access a CSS property
            if(document.getElementById){
                  return document.getElementById(layerID).style;
            }else if(document.all){
                  return document.all[layerID].style;
            }else if(document.layers){
                  return document.layers[layerID];
            }
      }
</script>
Bir katmanın CSS özelliklerine erişmek için:
   accessCSS("myLayer1")
yazılır. Örneğin:
  accessCSS("myLayer1").top ve
  accessCSS("myLayer1").zIndex

Kısaltılmış Kodlama

Kısaltılmış işlev daha önceki örneğe uygulanınca:
<script language="javascript" type="text/javascript">
    function moveLayerLR(layerID,how){
        // katmanı Sol ya da Sağa taşı
        accessCSS(layerID).left = parseInt(accessCSS(layerID).left) + how;
    }

    function moveLayerUD(layerID,how){
        // katmanı Yukarı ya da Aşağı taşı
        accessCSS(layerID).top = parseInt(accessCSS(layerID).top) + how;
    }
</script>

else edilir.

Buradaki kodlama hem daha kısa hem daha anlaşılır biçimdedir. Aslında her ikisinin de çalışma biçimi aynıdır.

Görünülüğü (Visibility) Değiştirme

Görünürlük özelliği bir katmanı göstermenizi ya da saklamanızı sağlar. Burada bir katmanın görünürlüğünü değiştiren işlev yazılmıştır.
   <div id="myLayer1" style="position:absolute;
                             left:100;top:100;
                             visibility:visible">
       This is our Layer
   </div> 
Görünülürlük konusuna başlamadan öce bu işin tarayıcılar arasında oldukça farklı yorumlandığını söylemekte yarar vardır. NN 4'de niteliklerde "show" ve "hide" sözcüklerini kullanmak gerekir. Diğer tarayıcılar, W3C'nin önerdiği gibi "visible" ve "hidden" sözcüklerini kullanırlar. Eğer:
    style="visibility:hidden"

tanımlıysa NN 4 katmanı doğru biçimde saklar ama bu değer "hide" olarak yorumlanır. Bu nedenle sorulduğunda değişkendeki değer "hidden" değil "hide" biçiminde ele alınmalıdır.

Burada ilk belirlenen görünürlüğün "hidden" ya da "hide" olduğudur. Eğer görünürlük "show" ya da "visible" ise onu saklanacak duruma çevirmek gerekir.

<script>
   function toggleVis(layerID){
      if(accessCSS(layerID).visibility=="hidden" ||
         accessCSS(layerID).visibility=="hide"){
            accessCSS(layerID).visibility= "visible";
      }else{
            accessCSS(layerID).visibility= "hidden";
      }
   }
</script> 

Bilinmesi gereken önemli bir konu daha var. Katmanın görünürlüğüne değer girilmezse onun değeri her zaman "görünür" varsayılmaktadır.

Bir başka Tarayıcı Uyumsuzluğu

Bir pencerenin içten içe eni (innerWidth) tarayıcıya bağımlıdır (bu alanda html gövdesi görüntülenir). Zaten DHTML konusundaki pekçok şey de taracıyı bağımlıdır. NN 4 ve NS 6'da :
   window.innerWidth ve window.innerHeight 
kullanılır. Ama IE'de:
   document.body.clientWidth ve document.body.clientHeight
kullanılır. Bu değerleri IW adlı değişkene aşağıdaki gibi taşırız:
if(window.innerWidth){
      var IW=window.innerWidth;
}else{
      var IW=document.body.clientWidth;
}
"document.body" kullanırken <body> en azından yarım da olsa yüklenmiş olmalıdır. Bu nedenle koda erişim ya "body" etiketi içinden olmalı ya da gövde yüklendikten sonra, onLoad ya da setTimeout() işlevleriyle kullanılmalıdır.

Evet, IW değişkenine "innerWidth" değeri atanmış oldu ama bu çok uzun süren bir kodlamadır. Daha kısa yolu koşul?doğru_komut:yalnış_komut biçiminde yazılan kodlamadır:

   var IW=window.innerWidth ? window.innerWidth :
                              document.body.clientWidth;
Bu işlem basit if-else komutlarını kısaltmak için çok kullanışlıdır.

Kaydırma koduna dönüldüğünde kodlamadaki interV evrensel bir değişken olarak IW değişkeniyle birlikte kullanıldığı anlaşılır (setTimeout() değerini saklar).
  function accessCSS(layerID){
      if(document.getElementById){
          return document.getElementById(layerID).style;
      }else if(document.all){
          return document.all[layerID].style;
      }else if(document.layers){
          return document.layers[layerID];
      }
  }
Yukarıdaki kodlama, katmanın CSS özelliklerine erişmek için kullanılır.
  function moveThisLayer(layerID){
      layerPos = parseInt(accessCSS(layerID).left);
      layerPos
Bu işlev katmanın o anki (x-koordinatı) yerini gösterir. Daha sonra sağdan taşmıyorsa (yani innerWidth değerini geçmezse) o değere üç ekler. Bu işlev kendisini 10 saniye sonra yeniden çalıştırarak döngü kurar.
<div id="ML" style="position:absolute;top:0;left:0">
   <a href="javascript:moveThisLayer('ML')"
         style="font-family:Verdana;
                font-size:24px">
       Hareket ettir
   </a>
   &nbsp; &nbsp;
   <a href="javascript:void(0)"
              onclick="clearTimeout(interV)"
              style="font-family:Verdana;
                     font-size:24px">
       Hareketi durdur
   </a>
</div>
Artık koda hareket gelmiştir. Şimdi bazı fare hareketinden söz etmenin zamanıdır.
Fare hareketini fark edebilmek ekranda bir şeylerin hareket etmesinden çok önemlidir. Bu özellik tarayıcı bağımlıdır... Netscape için e.pageX ya da e.pageY kullanılır. Burada "e" olay değişkenidir. IE için window.event.x ve window.event.y kullanılır. Aşağıdaki işlev bu değerleri tanımlar:
function returnMouseXCoord(e){
      mouseX = navigator.appName=="Netscape" ? e.pageX : event.x;
      return mouseX;
}

Katman Koordinatları

Bir katmanın köşesinin yerini saptamak kullanışlı olabilir:
    parseInt(accessCSS(layerID).top) ve
    parseInt(accessCSS(layerID).left)
Bu değerler bir katmanın üst ve sol kenarının değerini belirtir. Buraya kadar kolaydır. Asıl sorun sağ ve alt kenarın nasıl belirleneceğidir. CSS özellikleri arasında alt ve sağ kenarla ilgili bir tanımlama yoktur. Ama bir katmanın yüksekliğini ve enini alabiliriz. Bunları kullanarak sağ ve alt kenarı hesaplama olanağı doğar.

Sol kenarla katmanın enini toplayıp sağ kenarı, aynı biçimde üst kenarla yüksekliği toplayıp alt kenarı bulunabilir. Ama hemen sevinilmemelidir.
   parseInt(accessCSS(layerID).width)
ancak CSS içinde katman için açıkça en tanımı varsa, değerini verir. Tanım yapılmamışsa değer elde edemeyiz. Burada tarayıcıya bağlı kalmadan ve CSS ile en tanımı yapmadan değer nasıl bulunur incelenmiştir.

NN 4'de tarayıcının enini bulmak için:

   document.layers[layerID].clip.width ve
   document.layers[layerID].clip.height
kullanılır.

IE 4'de tarayıcının eni:

    document.all[layerID].offsetWidth ve
    document.all[layerID].offsetHeight
kullanılılarak bulunur.

Burada "style" sözcüğünün olmamasına dikkat edin. Çünkü offsetWidth ve offsetHeight CSS stilleri değildir.

IE 4'deki gibi IE 5 ve NS 6 de offsetWidth ve offsetHeight kullanır (burada katmanlara daha değişik yaklaşılır). IE 5 ve NS 6'da

   document.getElementById(layerID).offsetWidth ve
   document.getElementById(layerID).offsetHeight.
tanımları kullanılır.

Tarayıcı uyumsuzluklarından soysal bir işlev tanımlamak ilerideki kullanımlar için daha yararlı olabilir:

function getLayerWidth(layerID){
    if(document.getElementById){
      return parseInt(document.getElementById(layerID).offsetWidth);
    }else if(document.all){
      return parseInt(document.all[layerID].offsetWidth);
    }else if(document.layers){
      return parseInt(document.layers[layerID].clip.width);
    }
}

function getLayerHeight(layerID){
    if(document.getElementById){
      return parseInt(document.getElementById(layerID).offsetHeight);
    }else if(document.all){
      return parseInt(document.all[layerID].offsetHeight);
    }else if(document.layers){
      return parseInt(document.layers[layerID].clip.height);
    }
} 

Burada bilinmesi gereken diğer bir konu da farenin o anda hangi katmanın üzerinde olduğunun anlaşılmasıdır.

IE 4 ve IE 5'de bu oldukça kolaydır: "event.srcElement" kullanmak yeterlidir. NS 6'da (W3C önerilerindeki gibi) "event.target" kullanılır. NN 4 böyle bir özellik desteklemez. Bu nedenle dolaylı bir yol izlememiz gerekir. Eğer farenin koordinatları bilinirse, katmanların sol ve üst kenarlarından arama yaparak hangi katmanda farenin olduğunu bulunabilir.

function getLayerID(e){
    if(navigator.appName=="Netscape"){
        // if Netscape
        if(document.getElementById){
            // Bu kod NS 6 kullanıcıları içindir
            if(e.target.nodeName=="#text"){
                layerID=e.target.parentNode.id.toString();
            }else{
                layerID=e.target.id.toString();
            }
        }else if(document.layers){
            // Bu kod NN 4 kullanıcıları içindir
            var mouseX = e.pageX, mouseY = e.pageY;
            for (i=0;iparseInt(el.left) &&
                    mouseXparseInt(el.top) &&
                    mouseY

NS 6 kodu W3C DOM belgelerinde anlatıldığı için burada ayrıntılara girilmemiştir. NN 4 kodunda yapılanlar şöyle özetlenebilir: Önce farenin yeri belirlenir. Tüm katmanalar aranarak farenin, bulunan katmanın tam ortasında olup olmadığına bakılır (daha önceki işlevleri kullanmadan katmanın eni ve boyunu kullanmış olmamız bu değerlerin doğrudan girilmiş olduğunu gösterir). Aslında tarayıcı NN 4 olduğuna göre yukarıdaki işlevler de kullanılabilirdi.

Şimdi örneğimize gelebiliriz. Kodun uzun olması ve hemen anlaşılması sorun olur diye önce örneğe bakmakta yarar vardır: Örnek 5

Açılma/Koyulaşma (Fade out/Fade in)

Şimdi bir resmi ele alalım, bu resim yavaş yavaş kaybolurken bir başka resimle değişir ve yeni resim de yavaş yavaş koyulaşır. Burada IE özelliklerini kullandığımızdan Netscape kullanıcılarını kodun içinde dolanmalarını kaldırmak gerek. Bunu doğal olarak "document.all" ile yaparız. Hem IE 4 hem de IE 5 bu kodu kullanabilmektedir.

<div id="image1" style="position:absolute;filter:alpha(opacity=100)">
    <img src="img/pic1.gif">
</div>
<div id="image2" style="position:absolute;filter:alpha(opacity=0)">
    <img src="img/pic2.gif">
</div>

Geçirgenliğe Erişim

CSS filitre (filter) niteliğine erişmek için IE 4'de:
   document.all[layerID].style.filter
IE 5'de:
   document.getElementById(layerID).style.filter
Burada iki değişik kod kullanmak yerine
   document.all 
CSS'nin "alpha" özelliğine erişmek için:
   document.all[layerID].style.filter.alpha
kullanılır.
'alpha'nın "opacity" geçirgenlik özelliğine erişmek için:
   document.all[layerID].style.filter.alpha.opacity
kullanılır.
Bir resmi açıp, koyulaştırmak için kullanılacak kod şöyle olabilir:
<script>
    var i, j;

    /* Bu tanım evrensel (global) değişkenler
       için kullanılır. i değişkeni fadeOut() işlevini 
       j değişkeni de fadeIn() işlevini denetlemekte
       kullanılır 
    */

    function fadeOut(layerID){
        i-=2;
        document.all[layerID].filters.alpha.opacity=i;
        if(i!=0) setTimeout("fadeOut('"+layerID+"')",20);
    }

    /* Bu işlev belirtilen katmanı soluklaştırır. Önce i değişkenini
       alır ve değerini iki eksiltir. Sonra bu değeri katmana atar.
       Böylece i değeri geçirgenlik (opacity) değeri olur.
       Daha sonra setTimeout() işlemi aynı işlevin yeniden
       çalıştırılmasını sağlayarak bir döngü oluşturur. Soluklaşma
       bitince döngü durdurulur.
    */

    function fadeIn(layerID){
          j+=2;
          document.all[layerID].filters.alpha.opacity=j;
          if(j!=100) setTimeout("fadeIn('"+layerID+"')",20);
    }

    /* Burada belirtilen katman koyulaştırılır. Önce j değişkeninin
       değerini alır ve katmanın geçirgenlik değeri yapar. j değerini
       iki arttırır. Daha sonra setTimeout() işlemiyle aynı işlevi
       yeniden çalıştırarak döngü oluşturur. Değişken j'nin değeri 100
       olunca döngü durdurulur.
    */

    function fadeInOut(layerID1,layerID2){
          if(document.all){
                i=100; j=0;
                fadeOut(layerID1);
                setTimeout("fadeIn('"+layerID2+"')",200);
          }
    }
    /* Bu işlevin iki parametresi vardır. Birincisi
       soluklaşacak katmanın katman kimlik kodu (ya da
       kimlik adı). Sonra fadeOut işlevini kontrol eden
       değişkenin değerini 100 yapar. Başlangıçta katman
       hiç soluklaşmamış olarak görüntülenir. Bu işlev
       fadeIn() işlevini denetleyen değişkenin değerini
       de 0 yapar. Önce fadeOut() işlevini çalıştırır.
       O da kendisini çalıştırarak bir döngü oluşturur.
       fadeIn() işlevinin 200 milisaniye sonra başlamasına
       da olanak verir. Daha sonra fadeIn() kendisi çalıştırarak
       bir döngü oluşturacaktır.
    */

   // fadeInOut("image1","image2");
</script>

Netscape 6 aynısını yapabilir

Netscape, IE ile uyumlu olabilmek için kendi geçirgenlik özelliğini (opacity) yarattı. Değer "-moz-opacity" biçiminde tanımlanır ve 0-1 arasında değer alabilir. Aynı IE 4+ geçirgenliği gibi çalışır.

   <IMG src="img1.gif" id="img1" style="-moz-opacity:0.5">

Sayı kullanmanın yanında yüzde oranı da kullanılabilir. Çünkü 0.3 zaten 30% anlamına gelmektedir.

    <IMG src="img1.gif" id="img1" style="-moz-opacity:50%">

Daha sonra CSS niteliğine erişmek için :

    document.getElementById("img1").style.MozOpacity
kullanılır.

Tarayıcı bağımsız kod (NN 4 hariç)

Yukarıdaki kodun NS 6'da da çalışabilmesi için aşağıdaki biçime getirilmesi doğru olur.

<script>
   var i, j;

   function fadeOut(layerID){
      i-=2;
      if(document.all){
            // IE 4+ için (IE 4, IE 5, ve IE 6 dahil)
            document.all[layerID].filters.alpha.opacity=i;
      }else if(document.getElementById){
            // Eğer Netscape 6 -- Unutmayın
            //      IE 5 bu if deyimi için 
            //      doğru (true) değeri döndürür
            document.getElementById(layerID).MozOpacity=i+"%";
      }
      interVal = setTimeout("fadeOut('"+layerID+"')",20);
      if(i==0) clearTimeout(interVal);
   }

   function fadeIn(layerID){
      j+=2;
      if(document.all){
            // IE 4+ için (IE 4, IE 5, ve IE 6 dahil)
            document.all[layerID].filters.alpha.opacity=j;
      }else if(document.getElementById){
            // Eğer Netscape 6 -- Unutmayın
            //      IE 5 bu if deyimi için 
            //      doğru (true) değeri döndürür
            document.getElementById(layerID).MozOpacity=j+"%";
      }
      interVal = setTimeout("fadeIn('"+layerID+"')",20);
      if(j==100) clearTimeout(interVal);
   }

   function fadeInOut(layerID1,layerID2){
      if(document.all||document.getElementById){
           // IE 4+ için ve NS 6+ için
           i=100; j=0; 
           fadeOut(layerID1);
           setTimeout("fadeIn('"+layerID2+"')",200);
      }
   }

   // fadeInOut("image1","image2");
</script> 

Bir Katmanı ortalamak

Bir katmanı ortalamak için ekranın boyunu (innerWidth) ve katmanın enini bilmeliyiz. Daha sonra toplam sayfa eninden katmanın enini çıkarıp kalanı ikiye bölünce sol kenarın yerini buluruz. Bu değer de zaten sağ kenar kadardır.


Bu işlemin kodu

<script>
   var IW=window.innerWidth ? window.innerWidth : document.body.clientWidth;

   function accessCSS(layerID){
      if(document.getElementById){
         return document.getElementById(layerID).style;
      }else if(document.all){
         return document.all[layerID].style;
      }else if(document.layers){
         return document.layers[layerID];
      }
   }

   function getLayerWidth(layerID){
      if(document.getElementById){
         return parseInt(document.getElementById(layerID).offsetWidth);
      }else if(document.all){
         return parseInt(document.all[layerID].offsetWidth);
      }else if(document.layers){
         return parseInt(document.layers[layerID].clip.width);
      }
   }

   function centerLayer(layerID){
      accessCSS(layerID).left = (IW - getLayerWidth(layerID))/2;
   }
</script>

<div id="myLayer1" style="position:absolute;
                             top:170px;left:30px;
                             z-index:3;
                             height: 25px">
<a href="javascript:centerLayer('myLayer1')">
   Bu yazıyı ortalayın
</a>
</div>

Burada herşey çok açık olduğundan ayrıntılı bir açıklama yoktur. Önemli olan bir katmanı ortalarken onun eninin tanımlanması gerektiğidir.