Bir sayfanın dikey bir kaydırma çubuğuna sahip olup olmadığı algılansın mı?


121

Sadece basit bir JQ / JS'nin geçerli sayfanın / pencerenin (belirli bir öğenin değil) dikey bir kaydırma çubuğuna sahip olup olmadığını kontrol etmesini istiyorum.

Google, bana sadece bu temel özellik için aşırı derecede karmaşık görünen şeyler veriyor.

Bu nasıl yapılabilir?

Yanıtlar:


97
$(document).ready(function() {
    // Check if body height is higher than window height :)
    if ($("body").height() > $(window).height()) {
        alert("Vertical Scrollbar! D:");
    }

    // Check if body width is higher than window width :)
    if ($("body").width() > $(window).width()) {
        alert("Horizontal Scrollbar! D:<");
    }
});

14
+1 ancak kesinlik adına, bu yalnızca içeriğin görüntü alanından daha fazla genişleyip genişlemediğini kontrol eder. Öğesinin overflowözelliği hat bodyüzerinde bir hiddenyere ayarlanmışsa çalışmaz. Yine de bir vücutta gizli kalmak son derece nadirdir.
Pekka

4
Bu, gövde yüksekliği pencere yüksekliğiyle eşleşirse çalışmaz; bu, belge yüksekliği görüntü alanına tam olarak uyuyorsa, yatay bir kaydırma çubuğu eklenir . Vert'i zorlayacak. kaydırma çubuğu ancak belge / gövde / pencere yüksekliği aynı; bir tane olsa bile "dikey kaydırma çubuğunu" uyarmaz.
Monica Cellio'ya İftira Etmeyi Bırakın

2
Bunun $(document)yerine kullanmak zorunda olduğumu söylemeyi düşündüm $("body"), bu benim için çalıştı (genişlik / yükseklik üzerinde bir en boy oranına sahip mutlak konumlanmış bir konteynırım var)
am_

1
Chrome tarayıcısında, başlangıçta bir kaydırma çubuğu görüntülediği ve programlamadığım için bir tarayıcı davranışına benzeyen birkaç milisaniye içinde kaybolduğu rapor sayfam var. Yani bu işlev benim durumumda her zaman doğru olur ..
Dush

@TiuTalk for me $ ("body"]. Height () & $ (window) .height () aynı değeri veriyor, bunun yerine $ (document) .height ()> $ (window) .height () kullanıyorum ben mi.
SarangK

77

bunu dene:

var hasVScroll = document.body.scrollHeight > document.body.clientHeight;

Ancak bu size yalnızca dikey scrollHeight değerinin görüntülenebilir içeriğin yüksekliğinden büyük olup olmadığını söyleyecektir. hasVScrollDeğişken doğru veya yanlış içerecektir.

Daha kapsamlı bir kontrol yapmanız gerekirse, yukarıdaki koda aşağıdakileri ekleyin:

// Get the computed style of the body element
var cStyle = document.body.currentStyle||window.getComputedStyle(document.body, "");

// Check the overflow and overflowY properties for "auto" and "visible" values
hasVScroll = cStyle.overflow == "visible" 
             || cStyle.overflowY == "visible"
             || (hasVScroll && cStyle.overflow == "auto")
             || (hasVScroll && cStyle.overflowY == "auto");

1
+1 Güzel! Ve gerekli bilgisayar stili ile (bu soruya karışmamaya karar verdiğim nokta
buydu

haha evet Bunu yazmak için fazladan çaba gösterip göstermemeyi tartışıyordum çünkü çoğu durumda buna gerek yok.
Andy E

1
Bu, scrollHeight değerinin clientHeight değerinden büyük olup olmadığına bakılmaksızın, overflowY 'görünür' olduğunda hasVScroll'un doğru olmasına neden olur. Belki demek istedin cStyle.overflow === 'scroll'?
BT

5
Yukarıdaki kod çalışmıyor. Tarayıcı: Chrome 56. Url: news.greylock.com/…
Sebastien Lorber

1
@BT cStyle.overflow == "visible" , öğe document.body. Ancak olmalıdır (hasVScroll && cStyle.overflow == "görünür" && element.nodeName == "BODY"). Ayrıca belirttiğiniz cStyle.overflow === 'scroll'gibi kontrol etmesi gerekiyor .
mseifert

44

Önceki cevabı denedim ve $ ("body") ile çalışmıyor gibi görünüyor. Height () html yüksekliğini tam olarak temsil etmiyor.

Çözümü şu şekilde düzelttim:

// Check if body height is higher than window height :) 
if ($(document).height() > $(window).height()) { 
    alert("Vertical Scrollbar! D:"); 
} 

// Check if body width is higher than window width :) 
if ($(document).width() > $(window).width()) { 
    alert("Horizontal Scrollbar! D:<"); 
} 

18

Bu soruyu ölümden geri getirelim;) Google'ın size basit bir çözüm vermemesinin bir nedeni var. Özel durumlar ve tarayıcı tuhaflıkları hesaplamayı etkiler ve göründüğü kadar önemsiz değildir.

Maalesef, şimdiye kadar burada ana hatlarıyla verilen çözümlerle ilgili sorunlar var. Onları küçümsemek istemiyorum - harika başlangıç ​​noktalarıdır ve daha sağlam bir yaklaşım için gereken tüm temel özelliklere değinirler. Ancak diğer yanıtların herhangi birinden kodu kopyalayıp yapıştırmanızı tavsiye etmem çünkü

  • tarayıcılar arası güvenilir bir şekilde konumlandırılmış içeriğin etkisini yakalayamazlar. Vücut ölçüsüne dayalı cevaplar bunu tamamen gözden kaçırır (vücut, kendisi konumlandırılmadıkça bu tür içeriğin dengelenmiş ebeveyni değildir). Ve bu cevaplar kontrol eder $( document ).width()ve jQuery'nin belge boyutunu hatalı algılamasının.height() kurbanı olur .
  • Güvendiğinde window.innerWidth, tarayıcı destekliyorsa, kodunuzun, kaydırma çubuğunun genişliğinin genellikle 0 olduğu mobil tarayıcılarda kaydırma çubuklarını algılamamasına neden olurlar. Bunlar yalnızca geçici olarak bir kaplama olarak gösterilir ve belgede yer kaplamaz. . Mobilde yakınlaştırmak da bu şekilde bir sorun haline gelir (uzun hikaye).
  • İnsanlar açıkça taşmasını ayarlandığında algılama kaldığında bozulabilir hem htmlve bodyvarsayılan olmayan değerlere eleman (sonra ne olur katılan biraz - bakınız bu açıklamayı ).
  • Çoğu yanıtta, gövde dolgusu, sınırlar veya kenar boşlukları algılanmaz ve sonuçları bozar.

"Sadece işe yarayan" (öksürük) bir çözüm bulmak için hayal ettiğimden daha fazla zaman harcadım. Bulduğum algoritma artık bir .hasScrollbaryöntemi ortaya çıkaran jQuery.isInView eklentisinin bir parçası . Dilerseniz kaynağa bir göz atın .

Sayfanın tam kontrolüne sahip olduğunuz ve bilinmeyen CSS ile uğraşmak zorunda olmadığınız bir senaryoda, bir eklenti kullanmak aşırı olabilir - sonuçta, hangi uç durumların geçerli olduğunu ve hangilerinin geçerli olmadığını bilirsiniz. Ancak bilinmeyen bir ortamda güvenilir sonuçlara ihtiyacınız varsa, burada özetlenen çözümlerin yeterli olacağını düşünmüyorum. İyi test edilmiş bir eklenti kullanmanız daha iyidir - benimki veya başka biri.


Teşekkürler. Oldukça karmaşık! Geriye dönük uyumlu olmak istemiyorsanız / buna ihtiyacınız varsa, html5 tarayıcıları için daha kolay bir çözüm var mı? Demek istediğim, belki tarayıcı kodlayıcıları / w3c bize sadece bir öğede kaydırma çubuğu olup olmadığını söyleyecek kadar iyi olmuştur? ;-)
Leo

1
@Leo Farkında olduğumdan değil. Tek bir özelliği olan bir window.scrollbarsnesne var visible. Umut verici görünüyor ama değil. IE11 dahil IE'de desteklenmez. Ve size sadece bir kaydırma çubuğu olduğunu söylüyor - ancak hangisi değil. Test sayfasına buradan bakın .
hashchange

Teşekkürler @hashchange. Kulağa inanılmaz aptalca geliyor, sadece herhangi bir kaydırma çubuğu olup olmadığını söylüyor, bu yüzden sanırım bu sadece bir tür test. Yine de biraz umut verici. ;-)
Leo

1
@BT Tamam, harika. Şimdi sizi tavşan deliğinin girişine götürmeme izin verin;) İşte içeriğin pencereyi doldurmaya yetmediği bir demo . Algılama işleminiz FF'de çalışıyor ancak Chrome'da başarısız oluyor. Ve burada konumlandırılmış bir öğenin sayfanın çok aşağısına yerleştirildiği başka bir demo var . Algılama işleminiz Chrome'da çalışıyor ancak FF'de başarısız oluyor.
hashchange

1
@BT Ve sanırım taşma ayarlarıyla oynamaya başladığımızda bir sürü garip hata moduna girebiliriz çünkü davranışları biraz tuhaf , ama ben orada durdum.
hashchange

15

Bu benim için çalıştı:

function hasVerticalScroll(node){
    if(node == undefined){
        if(window.innerHeight){
            return document.body.offsetHeight> window.innerHeight;
        }
        else {
            return  document.documentElement.scrollHeight > 
                document.documentElement.offsetHeight ||
                document.body.scrollHeight>document.body.offsetHeight;
        }
    }
    else {
        return node.scrollHeight> node.offsetHeight;
    }
}

Vücut için sadece kullanın hasVerticalScroll().


Bu ileti dizisindeki Chrome'umda çalışan tek yanıt
Nertan Lucian

clientHeightoffsetHeightburada tercih edilir . Aksi takdirde kalın bir kenarlığınız olabilir ve varsa kaydırma çubuğu olmaz.
theicfire


3

İşin garibi, bu çözümlerden hiçbiri size bir sayfada dikey bir kaydırma çubuğu olup olmadığını söylemez.

window.innerWidth - document.body.clientWidthsize kaydırma çubuğunun genişliğini verecektir. Bu, IE9 + ile herhangi bir şeyde çalışmalıdır (daha düşük tarayıcılarda test edilmemiştir). (Veya soruyu kesin olarak cevaplamak için,!!(window.innerWidth - document.body.clientWidth)

Neden? Diyelim ki içeriğin pencere yüksekliğinden daha uzun olduğu ve kullanıcının yukarı / aşağı kaydırabildiği bir sayfanız var. Chrome'u bir Mac'te fare takılı olmadan kullanıyorsanız, kullanıcı bir kaydırma çubuğu görmez. Bir fareyi takın ve bir kaydırma çubuğu görünecektir. (Bu davranış geçersiz kılınabilir, ancak bu varsayılan AFAIK'tir).


Chrome-Mouse davranışının açıklaması, tutarsız davranış olduğunu düşündüğüm şeyi anlamama yardımcı oldu. Teşekkürler!
theisof

2

Vanila çözümü buldum

var hasScrollbar = function() {
  // The Modern solution
  if (typeof window.innerWidth === 'number')
    return window.innerWidth > document.documentElement.clientWidth

  // rootElem for quirksmode
  var rootElem = document.documentElement || document.body

  // Check overflow style property on body for fauxscrollbars
  var overflowStyle

  if (typeof rootElem.currentStyle !== 'undefined')
    overflowStyle = rootElem.currentStyle.overflow

  overflowStyle = overflowStyle || window.getComputedStyle(rootElem, '').overflow

    // Also need to check the Y axis overflow
  var overflowYStyle

  if (typeof rootElem.currentStyle !== 'undefined')
    overflowYStyle = rootElem.currentStyle.overflowY

  overflowYStyle = overflowYStyle || window.getComputedStyle(rootElem, '').overflowY

  var contentOverflows = rootElem.scrollHeight > rootElem.clientHeight
  var overflowShown    = /^(visible|auto)$/.test(overflowStyle) || /^(visible|auto)$/.test(overflowYStyle)
  var alwaysShowScroll = overflowStyle === 'scroll' || overflowYStyle === 'scroll'

  return (contentOverflows && overflowShown) || (alwaysShowScroll)
}


1
IE 11'de çalışmıyor. Window.innerWidth & document.documentElement.clientWidth her zaman aynıdır.
NLV

Onu düzeltti. Bu aynı işlev IE 11 için de geçerlidir. Sorun şuydu - stackoverflow.com/questions/17045132/…
NLV

Bunu Chrome 65'te test ettim ve çalışıyor. Ancak onu yatay kaydırma çubuklarına uyarladığımda, sonuç garip: Hem yatay hem de dikey kaydırma çubuğu görüntüleniyorsa, window.innerWidth > document.documentElement.clientWidthdoğrudur, ancak window.innerHeight > document.documentElement.clientHeightdeğildir. Bu durumda durum tam tersi gibi görünüyor. JS geliştiricisi değilim, sadece Selenium testleri için ihtiyacım var. İpuçları için minnettarım.
kriegaex

2
    <script>
    var scrollHeight = document.body.scrollHeight;
    var clientHeight = document.documentElement.clientHeight;
    var hasVerticalScrollbar = scrollHeight > clientHeight;

    alert(scrollHeight + " and " + clientHeight); //for checking / debugging.
    alert("hasVerticalScrollbar is " + hasVerticalScrollbar + "."); //for checking / debugging.
    </script>

Bu size bir kaydırma çubuğunuz olup olmadığını söyleyecektir. Hata ayıklamaya yardımcı olabilecek ve JavaScript uyarısı olarak görüntülenecek bazı bilgiler ekledim.

Bunu, kapanış gövde etiketinden sonra bir komut dosyası etiketine yerleştirin.


1

Kees C. Bakker'in cevabının güncellenmiş bir versiyonunu yazdım:

const hasVerticalScroll = (node) => {
  if (!node) {
    if (window.innerHeight) {
      return document.body.offsetHeight > window.innerHeight
    }
    return (document.documentElement.scrollHeight > document.documentElement.offsetHeight)
      || (document.body.scrollHeight > document.body.offsetHeight)
  }
  return node.scrollHeight > node.offsetHeight
}

if (hasVerticalScroll(document.querySelector('body'))) {
  this.props.handleDisableDownScrollerButton()
}

İşlev, sayfanın dikey bir kaydırma çubuğuna sahip olup olmamasına bağlı olarak doğru veya yanlış döndürür.

Örneğin:

const hasVScroll = hasVerticalScroll(document.querySelector('body'))

if (hasVScroll) {
  console.log('HAS SCROLL', hasVScroll)
}

1

kullanırım

public windowHasScroll()
{
    return document.body.clientHeight > document.documentElement.clientHeight;
}

1

Belgelerin kök öğesinin (yani html öğesi) genişliğini pencerenin iç kısmıyla karşılaştırmanız yeterlidir:

if ((window.innerWidth - document.documentElement.clientWidth) >0) console.log('V-scrollbar active')

Kaydırma çubuğu genişliğini de bilmeniz gerekiyorsa:

vScrollbarWidth = window.innerWidth - document.documentElement.clientWidth;

0

Projelerimden birinde diğer çözümler işe yaramadı ve taşma css özelliğini kontrol etmeye son verdim

function haveScrollbar() {
    var style = window.getComputedStyle(document.body);
    return style["overflow-y"] != "hidden";
}

ancak yalnızca kaydırma çubuğu, pervane değiştirilerek kaybolursa çalışacaktır, içerik pencereye eşitse veya pencereden daha küçükse çalışmayacaktır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.