HTML öğesinin kaydırma çubuklarına sahip olup olmadığını kontrol edin


113

Bir öğenin kaydırma çubuklarına sahip olup olmadığını kontrol etmenin en hızlı yolu nedir?

Elbette bir şey, öğenin görüntü alanından daha büyük olup olmadığını kontrol etmektir; bu, bu iki değeri kontrol ederek kolayca yapılabilir:

el.scrollHeight > el.offsetHeight || el.scrollWidth > el.offsetWidth

ancak bu, kaydırma çubuklarına sahip olduğu anlamına gelmez (yani aslında insanlar tarafından kaydırılabilir).

Soru

Kaydırma çubuklarını 1 çapraz tarayıcıda ve 2 javascript'te ( jQuery olmadığı gibi ) nasıl kontrol ederim ?

Yalnızca Javascript, çünkü olabildiğince küçük ek yüke ihtiyacım var, çünkü çok hızlı bir jQuery seçici filtresi yazmak istiyorum

// check for specific scrollbars
$(":scrollable(x/y/both)")

// check for ANY scrollbar
$(":scrollable")

Sanırım overflowstil ayarlarını kontrol etmem gerekecek ama bunu tarayıcılar arası bir şekilde nasıl yapabilirim?

Ek düzenleme

Sadece overflowstil ayarları değil . Bir öğenin kaydırma çubuğuna sahip olup olmadığını kontrol etmek göründüğü kadar önemsiz değildir. Yukarıda yazdığım ilk formül, öğenin bir sınırı olmadığında iyi çalışıyor, ancak varsa (özellikle kenarlık önemli ölçüde geniş olduğunda), offsetboyut boyuttan daha büyük olabilir , scrollancak öğe yine de kaydırılabilir. Biz aslında dan sınırları çıkarmak zorunda offsetelemanın gerçek kaydırılabilir viewport almak için boyut ve ile karşılaştırabilirsiniz scrollboyutta.

Gelecekte referans olması için

:scrollablejQuery seçici filtresi, .scrollintoview()jQuery eklentimde yer alıyor. Herhangi birinin ihtiyacı olursa tam kod blog yazımda bulunabilir . Gerçek çözümü sağlamasa da Soumya'nın kodu sorunu çözmeme önemli ölçüde yardımcı oldu. Beni doğru yönü gösterdi.

Yanıtlar:


118

Bunu birkaç hafta önce bir yerde buldum. Benim için çalıştı.

var div = document.getElementById('container_div_id');

var hasHorizontalScrollbar = div.scrollWidth > div.clientWidth;
var hasVerticalScrollbar = div.scrollHeight > div.clientHeight;

/* you'll get true/false */

12
Belli ki basitleştirilmiş bir örneğiniz var. Ya konteynırınız overflow:hiddenüzerine oturduysa? Fazla içerik olabilir, ancak yine de kaydırılamaz. Sorun göründüğü kadar basit değil.
Robert Koritnik

8
Bu kabul edilen çözüm olmayabilir, ancak benim için çalıştı. Gizlenmişse neden kaydırdığınızı bilmiyorum.
vol7ron

Bu kabul edilen çözüm olmayabilir, ancak benim için çalıştı. Robert, bu durumlar için, bu durumları test etmek için css overflow özelliğini de getiremez misin (örn. div.scrollHeight>div.clientHeight && !(div.style.overflow && div.style.overflow == 'hidden'))?
vol7ron

7
Bu çoğu durumda başarısız olur. Öğenizde taşma varsa: visible; genişlik: 200px; ve 500 piksel genişliğinde bir alt öğesi varsa, öğenizin kaydırma çubuğu yoktur, ancak 500 piksellik bir kaydırma genişliğine ve 200 piksellik bir clientWidth'e sahiptir.
Joseph Lennox

1
Taşma görünür veya gizliyse, genellikle kaydırma çubuğu bulunmaz.
Hubert Grzeskowiak

16

Deneyin:

Dikey kaydırma çubuğu için

el.scrollHeight> el.clientHeight

Yatay kaydırma çubuğu için

el.scrollWidth> el.clientWidth

Bunun en azından IE8 ve Firefox 3.6+ için çalıştığını biliyorum.


2
Şuna işaret ettim evet, bu bana belli bir elemanın göründüğünden daha büyük olduğunu söylüyor ama bu kaydırma çubuklarını gösterdiği anlamına gelmiyor. Olabilir overflow:hiddenve artık kaydırılamaz.
Robert Koritnik

1
Ve clientHeight / clientWidth değerleriyle kontrol etmek iyi sonuçlar vermez, çünkü öğelerin sınırları da olabilir ve bu ölçüye dahil değildir. Formülümü kontrol edin. Seninkinden daha iyi çalışıyor.
Robert Koritnik

Bu, clientHeight / clientWidth yerine kaydırma çubuklarını kontrol etmek için offsetHeight / offsetWidth kullanma konusunda doğrudur. Bunu belirttiğiniz için teşekkürler.
Gary

@RobertKoritnik - bu yüzden sadece belirli bir öğenin overflow:hiddenüzerinde olup olmadığını kontrol edin ... bu bence hala doğru cevap, çünkü en basit olanı.
vsync

14

Bu biraz zor görünebilir (veya olabilir) , ancak scrollTopve scrollLeftözelliklerini test edebilirsiniz .

0'dan büyüklerse, kaydırma çubukları olduğunu bilirsiniz. 0 ise, onları 1 olarak ayarlayın ve 1 sonucunu alıp almadığınızı görmek için tekrar test edin. Sonra tekrar 0'a ayarlayın.

Örnek: http://jsfiddle.net/MxpR6/1/

function hasScroll(el, direction) {
    direction = (direction === 'vertical') ? 'scrollTop' : 'scrollLeft';
    var result = !! el[direction];

    if (!result) {
        el[direction] = 1;
        result = !!el[direction];
        el[direction] = 0;
    }
    return result;
}

alert('vertical? ' + hasScroll(document.body, 'vertical'));
alert('horizontal? ' + hasScroll(document.body, 'horizontal'));

IE için farklı bir özellik olduğuna inanıyorum, bu yüzden bir dakika içinde güncelleyeceğim.

DÜZENLEME: IE bu özelliği destekliyor gibi görünüyor. (IE'yi şu anda test edemiyorum.)

http://msdn.microsoft.com/en-us/library/ms534618(VS.85).aspx


offsetHeightVe karşılaştırırsanız kaydırma çubuklarını kontrol etmek çok daha kolaydır clientHeight. İkincisi, kaydırma çubuğu mevcut olduğunda kaydırma çubuğu boyutuna göre her zaman daha küçüktür.
Robert Koritnik

@Robert: Daha kolay olduğundan emin değilim, ama nasıl çalıştığını anlıyorum. Daha sonra, bir öğede varsa overflow:scroll, kaydırma çubuklarının etkin olup olmadığına bakılmaksızın bunun kaydırılabilir olarak rapor edilmesini istediğinizi varsayıyorum . Elbette eklenmiş bir onscroll olayı varsa benim çözümümde sorunlar olabilir.
user113716

Pek sayılmaz. JQuery eklentimi kontrol ederseniz , gerçek kaydırılabilir ata bulmam gerekiyor, aksi takdirde bir öğeyi görünüme kaydıramam.
Robert Koritnik

8
@RobertKoritnik Doğru değil; bazı tarayıcılarda genişliği azaltmayan kaydırma çubukları olabilir. Örneğin bir OS X'te. Veya cihazlara dokunun.
daniel.gindi

1
her zaman yanlış döner
Fatih Erol

14

İşte başka bir çözüm:

Birkaç kişinin de belirttiği gibi, sadece kaydırma çubuğu olmayan taşma gizli vb. Öğelerde farklılık gösterdiklerinden, sadece offsetHeight ve scrollHeight'ı karşılaştırmak yeterli değildir. Bu yüzden, burada ayrıca eleman için hesaplanan stillerde taşmanın kaydırma mı yoksa otomatik mi olduğunu kontrol ediyorum:

var isScrollable = function(node) {
  var overflowY = window.getComputedStyle(node)['overflow-y'];
  var overflowX = window.getComputedStyle(node)['overflow-x'];
  return {
    vertical: (overflowY === 'scroll' || overflowY === 'auto') && node.scrollHeight > node.clientHeight,
    horizontal: (overflowX === 'scroll' || overflowX === 'auto') && node.scrollWidth > node.clientWidth,
  };
}

Eğer varsa overflow*, scrollher zaman bir kaydırma çubuğu olacaksa, bu yüzden istediğinizi düşünüyorum vertical: overflowY === 'scroll' || overflowY === 'auto' && node.scrollHeight > node.clientHeight, vs. (yani köşeli parantezleri kaldırın, böylece scroll*vs client*sadece ne zaman test overflow*edilir auto). Aksi takdirde bu en doğru çözüm gibi görünüyor.
Jake

@Jake ScrollHeight <clientHeight kaydırma taşması durumunda, kaydırma çubukları orada olacak, ancak devre dışı bırakılacaklar (yani öğe kaydırılamaz). Bu yüzden uygulamaya bağlı olduğunu düşünüyorum. Değişikliğiniz, durumu ne olursa olsun, yalnızca kaydırma çubuklarını kontrol etmek istediğiniz için geçerlidir. Benim için, bunu ortaya çıkardığımda, bir bileşen için otomatik kaydırmayı uygulamaya çalışıyordum, bu nedenle kaydırma çubuklarını devre dışı bırakmak bu durumda işe yaramaz. Bu soru için de durum böyle görünüyor ("insanlar tarafından kaydırılması gerekiyor")
lotif

6

Belki partiye biraz geç kaldım ama ...

E.offsetWidth ve e.clientWidth ile kaydırma çubuklarını tespit edebileceğinize inanıyorum. Kaydırma genişliği, kenarlıkları ve kaydırma çubuklarını, dolgu ve genişliği içerir. İstemci genişliği, dolgu ve genişliği içerir. Bakınız:

https://developer.mozilla.org/en/DOM/element.offsetWidth (ikinci resim) https://developer.mozilla.org/en/DOM/element.clientWidth (ikinci resim)

Kontrol etmeniz gerekenler:

  1. Öğenin hesaplanan / basamaklı / geçerli stil kullanılarak otomatik / kaydırmaya (overflowX / Y dahil) ayarlı olup olmadığı.
  2. Öğe taşma otomatik / kaydırmaya ayarlanmışsa. OffsetWidth ve clientWidth değerlerini belirleyin.
  3. ClientWidth offsetWidth - right border değerinden daha küçükse (yine hesaplanan / basamaklı / geçerli stilde bulunur), o zaman bir kaydırma çubuğunuz olduğunu bilirsiniz.

Dikey için de aynısını yapın (offset / clientHeight).

IE7, bazı öğeler için 0 olarak bir clientHeight bildiriyor (nedenini kontrol etmedim), bu nedenle her zaman ilk taşma kontrolüne ihtiyacınız var.

Bu yardımcı olur umarım!


3

Kaydırma çubuklarının varlığını kontrol etme durumunda birkaç sorun vardır, bunlardan biri, Mac'te görünür bir kaydırma çubuğuna sahip olmamanızdır, bu nedenle yukarıdaki tüm çözümlerin her ikisi de size doğru bir cevap vermez.

Bu nedenle, tarayıcının oluşturması çok sık olmadığından, kaydırmayı değiştirerek kaydırmayı kontrol edebilir ve ardından geri ayarlayabilirsiniz:

const hasScrollBar = (element) => {
  const {scrollTop} = element;

  if(scrollTop > 0) {
    return true;
  }

  element.scrollTop += 10;

  if(scrollTop === element.scrollTop) {
    return false;
  }

  // undoing the change
  element.scrollTop = scrollTop;
  return true;
};


1

Yukarıdaki çözümlerden hiçbiri benim için işe yaramadığı için (şimdiye kadar) burada dolaşıyorum. Bir Div'in kaydırma yüksekliğini ofsetYüksekliği ile karşılaştırarak biraz başarı elde ettim

var oh = $('#wrapDiv').get(0).offsetHeight;
var sh = $('#wrapDiv').get(0).scrollHeight;

Şimdiye kadar bana doğru bir karşılaştırma yapıyor gibi görünüyor. Bunun meşru olup olmadığını bilen var mı?


2
Bence scrollHeight ve clientHeight istiyorsun: stackoverflow.com/questions/4106538/…
zengin yeniden

1

For IE11 (Internet Explorer 11) mantığı değiştirmek zorunda:

// Subtract 3 (a small arbitrary number) to allow for IE reporting a difference of 1 when no scrollbar is present
var hasVerticalScrollbar = div.scrollHeight - 3 > div.clientHeight;

Bunun nedeni, IE'nin scrollHeight'ı clientHeight'tan 1 büyük, kaydırma çubuğu olmadığında, ancak bir kaydırma çubuğu mevcut olduğunda yaklaşık 9 daha büyük olarak bildirmesidir.


0

Tüm web sayfası için bir kaydırma çubuğu olup olmadığını bilmeniz gerekiyorsa ve tam tarayıcı desteğiyle bunu kullanabilirsiniz:

const hasScrollbar = document.body.scrollHeight > window.innerHeight

Bunun window.innerHeightyerine kullanmak önemlidir , document.body.clientHeightçünkü bazı mobil tarayıcılarda clientHeight adres çubuğunun boyutunu almaz , ancak scrollHeight alır , bu nedenle yanlış hesaplamalar alırsınız.


-5

bu cevapların hiçbiri doğru değil. bunu kullanmalısın:

var div = document.getElementById('container_div_id');

var hasHorizontalScrollbar = (div.offsetWidth > div.clientWidth);
var hasVerticalScrollbar = (div.offsetHeight > div.clientHeight);

Bu, 6 yıl önce kabul edilen cevaptan kopyalandığı / yapıştırıldığı ve bir şeyi mantıksal değere dönüştürmek için parantezlere ihtiyacınız olmadığı için olumsuz oy verildi.
moto

-6

İçine% 100 geniş bir eleman ekleyin. Ardından taşmayı gizli olarak ayarlayın. Öğenin hesaplanan stili (jQ'dan) değişirse, üst öğenin bir kaydırma çubuğu vardı.

DÜZENLEME: Görünüşe göre getComputedStyle gibi bir çapraz tarayıcı yöntemi istiyorsunuz . Deneyin:

function getCSS(_elem, _style)
{
    var computedStyle;
    if (typeof _elem.currentStyle != 'undefined')
        computedStyle = _elem.currentStyle;
    else
        computedStyle = document.defaultView.getComputedStyle(_elem, null);
    return computedStyle[_style];
}

1
Bunun için zaten jQuery kullanacak olsaydım, sadece otomatik olarak mı yoksa kaydırmaya$(el).css("overflow/overflowX/overflowY") mı ayarlı olduğunu görmeyi tercih ederim . Ancak jQuery kullanmaktan kaçınmak isterim.
Robert Koritnik

16
CSS stilleri size bir öğenin kaydırma çubuklarına sahip olup olmadığını SÖZMEZ. Sadece olsun veya olmasın bu olabilir kaydırma çubukları var. Belki iç öğenin genişliğini belirlemek için çapraz tarayıcı yöntemi bulabilir misiniz?
Soumya

@ Soumya92: Kaydırılabilir ve gerçek boyut arasındaki boyut karşılaştırması önemsizdir ve bunu yukarıya yazdım ... Şimdi kontrol etmem gereken tek şey, belirli bir öğedeki mevcut taşma ayarı için.
Robert Koritnik

@ Soumya92: Tam olarak ihtiyacım olan şey bu. computedStyle = el.currentStyle || document.defaultView.getComputedStyle(el, null);
Birleştirme

Bir şey daha: Bu ne kadar çapraz tarayıcı? Bununla hangi tarayıcılar destekleniyor?
Robert Koritnik
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.