Javascript Yazılım Kuralları (JS)

23 Aralık 2007

Pencere boyutları ve kaydırma

Tarayıcı penceresinin boyutlarını bulma.
  • Clue tarayıcısı yalnız pencere enini hesaplar.
  • Tkhtml Hv3 body/documentElement clientHeight/Width değerlerini ters anlar - Eylül 2007'den önceki sürümler innerHeight/Width de desteklemez. Bu nedenle bu kodlamayla çalışmaz.
belge alanının yazılacak bölümüne ilişkin bilgi veren bazı değişmezler vardır. Belge yüklenmeden bular kullanıma açık değildir ve bunlara erişimde kullanılan yöntemler tümüyle tarayıcı bağımlıdır. Var olan değişmezler şöyledir:

window.innerHeight/Width
Bir çok tarayıcı tarafından desteklenir, ama en önemlisi IE tarafından desteklenmez.
document.body.clientHeight/Width
Bir çok tarayıcı tarafından desteklenir, IE de dahil
document.documentElement.­clientHeight/Width
Pek çok DOM tarayıcısı tarafından desteklenir, IE de dahil


Bu biraz karışık çünkü "clientHeight/Width" özelliği değişik tarayıcılarda değişik anlamlara gelebilir. Belge tipi tanımının tetiklenmesine bağımlı olarak tarayıcının "strict" konumuna ya da "quirks" konumuna göre değişik sonuçlar verir. Bazı koşullarda pencerenin boyutlarına ilişkin bilgi verirken, bazen pencere içindeki belgenin boyutları hakkında bilgi verir. Değişik konum ve tarayıcılarda ne anlamlar oluştuğu aşağıdaki tabloda anlatılmıştır:

Özellikler ve neye yaradıkları

Browser window. innerHeight document. body. clientHeight document. documentElement. clientHeight
Opera 9.5+ strictwindowdocumentwindow
Opera 9.5+ quirkswindowwindowdocument
Opera 7-9.2windowwindowdocument
Opera 6windowwindowN/A
Mozilla strictwindowdocumentwindow
Mozilla quirkswindowwindowdocument
KHTMLwindowdocumentdocument
Safariwindowdocumentdocument
iCab 3windowdocumentdocument
iCab 2windowwindowN/A
IE 6+ strictN/Adocumentwindow
IE 5-7 quirksN/Awindow0
IE 4N/AwindowN/A
ICEbrowserwindowwindowdocument
Tkhtml Hv3windowwindowdocument
Netscape 4windowN/AN/A


Gördüğünüz gibi tarayıcılar en azından bir özellikte uyum sağlarlar. O da; "innerHeight". IE kafasını toplayamayan tek tarayıcıdır. Onun etkisiyle diğer tarayıcılar ileride belki "clientHeight" özelliğinden vaz geçerler. Şimdilik hemen tüm tarayıcılar "window.innerHeight/Width" desteklemektedir. O halde bunu kullanmak daha uygundur. IE 'strick' konumundayken değerleri değiş tokuş etmektedir. İyi ki 'quicks' konumunda '0' değeri döndürüyor. Bunun anlamı: documentElement'in özelliklerinde bir değer olması ve tarayıcı window nesnesinde bu özellikleri desteklememesi bize bu tarayıcının IE olduğunu ve 'strict' konumunda olduğunu belirtir.

En kesin yöntem aşağıdaki algoritmanın kullanımıyla bulunur. Gelecekteki tarayıcılarda sorun olabilir. Bu da çok rahat olunamayacak bir durumdur:
  1. Eğer 'window.innerHeight/Width' varsa, buna tümüyle güvenilebilir, bunu kullanın
  2. Aksi halde eğer 'document.documentElement.clientHeight/Width' varsa ve herhangi biri sıfırdan büyükse onu kullanın.
  3. Akis halde 'document.body.clientHeight/Width' kullanın.
IE 6+ standartları uyumlu konum içindeyse (pencere 0px ile 0px değerine düşürülmüşse) bu algoritmada hata vardır. Bunun oluşma biçimi kullanıcının bilerek pencereyi küçültmesindendir. Bundan başka, yalnız belgenin yüksekliği verilirse, yine de problem olmayabilir. Aşağıdaki kodlamada önerilen algoritmayı uygular.
function alertSize() {
  var myWidth = 0, myHeight = 0;
  if( typeof( window.innerWidth ) == 'number' ) {
    //Non-IE
    myWidth = window.innerWidth;
    myHeight = window.innerHeight;
  } else if( document.documentElement &&
            ( document.documentElement.clientWidth ||
              document.documentElement.clientHeight ) ) {
    //IE 6+ in 'standards compliant mode'
    myWidth = document.documentElement.clientWidth;
    myHeight = document.documentElement.clientHeight;
  } else if( document.body &&
            ( document.body.clientWidth ||
              document.body.clientHeight ) ) {
    //IE 4 compatible
    myWidth = document.body.clientWidth;
    myHeight = document.body.clientHeight;
  }
  window.alert( 'Width = ' + myWidth );
  window.alert( 'Height = ' + myHeight );
}
Bunu burada deneyin: pencerenin iç boyutlarını alın.

Not: Tarayıcılar eni ya kaydırma çubuğunun dışından ya da içinden ölçerler (eğer varsa). Hiçbir yerde bu sorunun üstesinden gelecek bir yol gösterilmemiştir.

Pencerenin ne kadar kaydırıldığını bulmak

  • OmniWeb 4.2-, NetFront 3.3- ve Clue tarayıcıları bunu çözecek bir yol göstermezler.
  • Safari and OmniWeb 4.5+ hataları vardır. Hatalar kodlamayı etkilemez.
Belgede çeşitli etkileri yaratmaya çalışırken (kar yağması gibi ya da daha ciddi olarak okuyucu tarafından sayfa kaydırılırken aynı yerde menüleri durdurmak gibi) karşılaşılan sorunlar vardır. Aslında kaydırmanın başlangıçtan uzaklığı yatay ve düşey olarak bilinmektedir.

Bunu bulmanın üç ayrı yolu vardır ama pencerenin boyutlarını bulmaktan daha kolaydır. Bir çok tarayıcı "window.pageXOffset/pageYOffset" destekler. Bunlara güvenilebilir. Yine tuhaf olan IE, "document.body.scrollLeft/Top" sunuyor olmasıdır. 'strict' konumunda IE 6 ve birkaç tane daha tarayıcı "document.documentElement.scrollLeft/Top" sunar.

Eğer "scrollLeft/Top" özelliği hem "document.body" ve hem de "document.documentElement" tarafından sunulursa, bunların kullanımı Safari and OmniWeb 4.5+ hariç diğerlericwndeyle güvenlidir. Onlarda da kayma 0 ise -8 döndürür ama diğerlerini doğru iletirler. Ancak bunlar "window.pageXOffset/pageYOffset" değerlerini doğru sunabildiklerine göre kodlamada sorun olmaz.

Aşağıdaki kodlama kayma uzaklıklarını verir.
function getScrollXY() {
  var scrOfX = 0, scrOfY = 0;
  if( typeof( window.pageYOffset ) == 'number' ) {
    //Netscape compliant
    scrOfY = window.pageYOffset;
    scrOfX = window.pageXOffset;
  } else if( document.body &&
           ( document.body.scrollLeft ||
             document.body.scrollTop ) ) {
    //DOM compliant
    scrOfY = document.body.scrollTop;
    scrOfX = document.body.scrollLeft;
  } else if( document.documentElement &&
           ( document.documentElement.scrollLeft ||
             document.documentElement.scrollTop ) ) {
    //IE6 standards compliant mode
    scrOfY = document.documentElement.scrollTop;
    scrOfX = document.documentElement.scrollLeft;
  }
  return [ scrOfX, scrOfY ];
}
Artık bu kodlamadaki yolla yapılacak işi kurmak kolay olacaktır.