ตรวจสอบว่าเพจมีแถบเลื่อนแนวตั้งหรือไม่?


121

ฉันแค่ต้องการ JQ / JS แบบง่ายๆเพื่อตรวจสอบว่าหน้า / หน้าต่างปัจจุบัน (ไม่ใช่องค์ประกอบเฉพาะ) มีแถบเลื่อนแนวตั้งหรือไม่

Googling ให้ข้อมูลที่ดูซับซ้อนเกินไปสำหรับคุณลักษณะพื้นฐานนี้

จะทำได้อย่างไร?

คำตอบ:


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 แต่เพื่อความถูกต้องสิ่งนี้จะตรวจสอบว่าเนื้อหาขยายไปไกลกว่าวิวพอร์ตหรือไม่ หากoverflowคุณสมบัติของคุณสมบัติbodyถูกตั้งค่าเป็นที่hiddenใดที่หนึ่งตามบรรทัดจะไม่ทำงาน แม้ว่าการซ่อนอยู่บนร่างกายนั้นหายากมาก
Pekka

4
วิธีนี้ใช้ไม่ได้หากความสูงของร่างกายตรงกับความสูงของหน้าต่างซึ่งในกรณีนี้ถ้าความสูงของเอกสารตรงกับวิวพอร์ตทุกประการแล้วแถบเลื่อนแนวนอนจะถูกเพิ่มเข้าไป มันจะบังคับให้จุดยอด แถบเลื่อน แต่ doc / body / window สูงเท่ากัน มันจะไม่แจ้งเตือน "แถบเลื่อนแนวตั้ง" แม้ว่าจะมีอยู่ก็ตาม
หยุดใส่ร้าย Monica Cellio

2
แค่คิดว่าฉันจะพูดถึงว่าฉันต้องใช้$(document)แทน$("body")สิ่งนี้ใช้ได้ผลกับฉันเมื่อร่างกายไม่มี (ฉันมีคอนเทนเนอร์ที่มีตำแหน่งแน่นอนที่มีอัตราส่วนกว้างยาว / สูง)
am_

1
ฉันมีหน้ารายงานบนเบราว์เซอร์ Chrome ซึ่งในตอนแรกจะแสดงแถบเลื่อนและหายไปในเวลาไม่กี่มิลลิวินาทีซึ่งดูเหมือนพฤติกรรมของเบราว์เซอร์เนื่องจากฉันไม่ได้ตั้งโปรแกรม ดังนั้นฟังก์ชันนี้จึงคืนค่าจริงเสมอในกรณีของฉัน ..
Dush

@TiuTalk สำหรับฉัน $ ("body"). height () & $ (window) .height () ให้ค่าเดียวกัน แต่ฉันใช้ $ (document) .height ()> $ (window) .height () แทน ผม.
SarangK

77

ลองสิ่งนี้:

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

สิ่งนี้จะบอกคุณได้ก็ต่อเมื่อเลื่อนแนวตั้งความสูงใหญ่กว่าความสูงของเนื้อหาที่ดูได้ hasVScrollตัวแปรจะมีจริงหรือเท็จ

หากคุณต้องการตรวจสอบอย่างละเอียดให้เพิ่มสิ่งต่อไปนี้ในโค้ดด้านบน:

// 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 ดี! และด้วยรูปแบบการคำนวณที่จำเป็น (ซึ่งเป็นจุดที่ฉันตัดสินใจที่จะไม่เกี่ยวข้องกับคำถามนี้)
Pekka

ใช่ฉันกำลังชั่งใจว่าจะพยายามเขียนมันมากขึ้นหรือไม่เพราะในหลาย ๆ กรณีมันไม่จำเป็น
Andy E

1
สิ่งนี้ส่งผลให้ hasVScroll เป็นจริงเมื่อใดก็ตามที่ overflowY ถูก 'มองเห็นได้' ไม่ว่า scrollHeight จะมากกว่า clientHeight หรือไม่ บางทีคุณอาจหมายถึงcStyle.overflow === 'scroll'?
BT

5
รหัสข้างต้นไม่ทำงาน เบราว์เซอร์: Chrome 56. Url: news.greylock.com/…
Sebastien Lorber

1
@BT cStyle.overflow == "visible" สามารถแสดงแถบเลื่อนเมื่อองค์ประกอบเป็นไฟล์document.body. แต่ควรเป็น (hasVScroll && cStyle.overflow == "visible" && element.nodeName == "BODY") นอกจากนี้ยังต้องตรวจสอบcStyle.overflow === 'scroll'ตามที่คุณชี้ให้เห็น
mseifert

44

ฉันลองใช้คำตอบก่อนหน้านี้แล้วและดูเหมือนว่า $ ("body") ใช้งานไม่ได้ความสูง () ไม่จำเป็นต้องแสดงถึงความสูงของ html ทั้งหมด

ฉันได้แก้ไขวิธีแก้ไขแล้วดังนี้:

// 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

มาเอาคำถามนี้กลับมาจากความตายกันเถอะ) มีเหตุผลที่ Google ไม่ได้ให้คำตอบง่ายๆแก่คุณ กรณีพิเศษและนิสัยใจคอของเบราว์เซอร์มีผลต่อการคำนวณและไม่ได้เป็นเรื่องเล็กน้อยอย่างที่คิด

ขออภัยขณะนี้ยังมีปัญหากับแนวทางแก้ไขที่อธิบายไว้ที่นี่ ฉันไม่ได้ตั้งใจที่จะดูหมิ่นพวกเขาเลย แต่เป็นจุดเริ่มต้นที่ยอดเยี่ยมและสัมผัสกับคุณสมบัติหลักทั้งหมดที่จำเป็นสำหรับแนวทางที่แข็งแกร่งยิ่งขึ้น แต่ฉันไม่แนะนำให้คัดลอกและวางโค้ดจากคำตอบอื่น ๆ เนื่องจาก

  • พวกเขาไม่จับเอฟเฟกต์ของเนื้อหาที่อยู่ในตำแหน่งด้วยวิธีการข้ามเบราว์เซอร์ที่เชื่อถือได้ คำตอบที่ขึ้นอยู่กับขนาดของร่างกายพลาดสิ่งนี้ทั้งหมด (เนื้อหาไม่ได้เป็นส่วนชดเชยของเนื้อหาดังกล่าวเว้นแต่จะอยู่ในตำแหน่งตัวเอง) และคำตอบของผู้ตรวจสอบ$( document ).width()และ.height()ตกเป็นเหยื่อของการตรวจสอบรถของ jQuery ขนาดเอกสาร
  • การอาศัยwindow.innerWidthว่าเบราว์เซอร์รองรับทำให้โค้ดของคุณไม่สามารถตรวจพบแถบเลื่อนในเบราว์เซอร์มือถือซึ่งโดยทั่วไปความกว้างของแถบเลื่อนจะเป็น 0 โดยทั่วไปจะแสดงเป็นภาพซ้อนทับชั่วคราวและไม่ใช้พื้นที่ในเอกสาร . การซูมบนมือถือก็กลายเป็นปัญหาเช่นกัน (เรื่องยาว)
  • การตรวจจับสามารถยกเลิกได้เมื่อผู้คนตั้งค่าการล้นของทั้งองค์ประกอบhtmlและbodyองค์ประกอบเป็นค่าที่ไม่ใช่ค่าเริ่มต้นอย่างชัดเจน(สิ่งที่เกิดขึ้นมีส่วนเกี่ยวข้องเล็กน้อย - ดูคำอธิบายนี้ )
  • ในคำตอบส่วนใหญ่จะตรวจไม่พบการเว้นช่องตัวถังเส้นขอบหรือระยะขอบและบิดเบือนผลลัพธ์

ฉันใช้เวลามากกว่าที่จะจินตนาการได้ในการหาวิธีแก้ปัญหาที่ "ใช้ได้ผล" (ไอ) ขั้นตอนวิธีการที่ผมได้มาด้วยตอนนี้เป็นส่วนหนึ่งของปลั๊กอินjQuery.isInViewซึ่ง exposes วิธี ดูแหล่งที่มาหากคุณต้องการ.hasScrollbar

ในสถานการณ์ที่คุณสามารถควบคุมเพจได้อย่างสมบูรณ์และไม่จำเป็นต้องจัดการกับ CSS ที่ไม่รู้จักการใช้ปลั๊กอินอาจจะมากเกินไปเพราะคุณจะรู้ว่ากรณีขอบใดที่ใช้และกรณีใดที่ไม่ใช้ อย่างไรก็ตามหากคุณต้องการผลลัพธ์ที่เชื่อถือได้ในสภาพแวดล้อมที่ไม่รู้จักฉันคิดว่าวิธีแก้ปัญหาที่อธิบายไว้ที่นี่จะไม่เพียงพอ คุณควรใช้ปลั๊กอินที่ผ่านการทดสอบมาเป็นอย่างดีไม่ว่าจะเป็นของฉันหรือของใครก็ตาม


ขอบคุณ ค่อนข้างซับซ้อน! หากคุณไม่ต้องการ / จำเป็นต้องเข้ากันได้แบบย้อนหลังอาจมีวิธีแก้ปัญหาที่ง่ายกว่าสำหรับเบราว์เซอร์ html5 หรือไม่? ฉันหมายถึงบางที coders เบราว์เซอร์ / w3c ดีพอที่จะบอกเราว่ามีแถบเลื่อนหรือไม่ในองค์ประกอบ? ;-)
ลีโอ

1
@ ลีโอไม่ใช่ว่าฉันจะรู้ มีwindow.scrollbarsวัตถุที่มีคุณสมบัติเดียวคือvisible. ฟังดูมีแนวโน้ม แต่ไม่ใช่ ไม่รองรับใน IE รวมถึง IE11 และมันก็จะบอกคุณว่ามีแถบเลื่อน - แต่ไม่เป็นที่หนึ่ง ดูหน้าทดสอบที่นี่
hashchange

ขอบคุณ @hashchange มันฟังดูโง่มากที่มันบอกว่ามีแถบเลื่อนหรือเปล่าดังนั้นฉันเดาว่ามันเป็นแค่การทดสอบบางอย่าง แม้ว่าจะมีแนวโน้มเล็กน้อย ;-)
ลีโอ

1
@BT โอเคดีมาก ตอนนี้ให้ฉันพาคุณไปที่ทางเข้าของโพรงกระต่าย;) นี่คือการสาธิตที่เนื้อหาไม่เพียงพอที่จะเติมเต็มหน้าต่าง การตรวจจับของคุณทำงานใน FF แต่ล้มเหลวใน Chrome และนี่คือการสาธิตอีกอย่างหนึ่งที่มีการวางองค์ประกอบในตำแหน่งไว้ในหน้า การตรวจจับของคุณทำงานใน Chrome แต่ล้มเหลวใน FF
hashchange

1
@BT และฉันเดาว่าเราสามารถเข้าสู่โหมดความล้มเหลวแปลก ๆ มากมายเมื่อเราเริ่มเล่นกับการตั้งค่าที่มากเกินไปเพราะพฤติกรรมของพวกเขาแปลกไปเล็กน้อยแต่ฉันหยุดอยู่ตรงนั้น
hashchange

15

อันนี้ใช้ได้ผลสำหรับฉัน:

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;
    }
}

สำหรับร่างกายเพียงใช้hasVerticalScroll().


นี่เป็นคำตอบเดียวในชุดข้อความนี้ที่ใช้ได้กับ Chrome ของฉัน
Nertan Lucian

clientHeightเป็นที่นิยมมากกว่าoffsetHeightที่นี่ มิฉะนั้นคุณสามารถมีขอบหนาและกลับมาไม่มีแถบเลื่อนเมื่อมี
theicfire


3

วิธีแก้ปัญหาเหล่านี้ไม่แปลกที่จะบอกคุณได้ว่าเพจมีแถบเลื่อนแนวตั้งหรือไม่

window.innerWidth - document.body.clientWidthจะให้ความกว้างของแถบเลื่อน สิ่งนี้ควรใช้ได้กับทุกสิ่งที่ IE9 + (ไม่ได้ทดสอบในเบราว์เซอร์ที่น้อยกว่า) (หรือเพื่อตอบคำถามอย่างเคร่งครัด!!(window.innerWidth - document.body.clientWidth)

ทำไม? สมมติว่าคุณมีหน้าที่มีเนื้อหาสูงกว่าความสูงของหน้าต่างและผู้ใช้สามารถเลื่อนขึ้น / ลงได้ หากคุณใช้ Chrome บน Mac โดยไม่ได้เสียบเมาส์ผู้ใช้จะไม่เห็นแถบเลื่อน เสียบเมาส์แล้วแถบเลื่อนจะปรากฏขึ้น (โปรดทราบว่าพฤติกรรมนี้สามารถลบล้างได้ แต่นั่นคือ AFAIK เริ่มต้น)


คำอธิบายเกี่ยวกับพฤติกรรมของ Chrome-Mouse ช่วยให้ฉันทราบว่าสิ่งที่ฉันคิดว่าเป็นพฤติกรรมที่ไม่สอดคล้องกัน ขอบคุณ!
Theisof

2

ฉันพบสารละลายวานิลลา

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. window.innerWidth & document.documentElement.clientWidth จะเหมือนกันเสมอ
NLV

ซ่อมมัน. ฟังก์ชันเดียวกันนี้ใช้ได้กับ IE 11 ด้วย ปัญหาคือ - stackoverflow.com/questions/17045132/…
NLV

ฉันทดสอบสิ่งนี้ใน Chrome 65 และใช้งานได้ แต่เมื่อฉันปรับให้เป็นแถบเลื่อนแนวนอนผลลัพธ์ที่ได้ก็แปลก: หากแสดงแถบเลื่อนทั้งแนวนอนและแนวตั้งwindow.innerWidth > document.documentElement.clientWidthเป็นจริง แต่window.innerHeight > document.documentElement.clientHeightไม่ใช่ ดูเหมือนว่าจะเป็นอีกทางหนึ่งในกรณีนี้ ฉันไม่ใช่นักพัฒนา JS ฉันแค่ต้องการมันสำหรับการทดสอบซีลีเนียม ฉันรู้สึกขอบคุณสำหรับคำใบ้
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>

อันนี้จะบอกคุณว่าคุณมีแถบเลื่อนหรือไม่ ฉันได้รวมข้อมูลบางอย่างที่อาจช่วยในการดีบักซึ่งจะแสดงเป็นการแจ้งเตือน JavaScript

ใส่สิ่งนี้ในแท็กสคริปต์หลังแท็กเนื้อหาปิด


1

ฉันเขียนคำตอบของ Kees C.Bakker เวอร์ชันปรับปรุง:

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()
}

ฟังก์ชันจะคืนค่าจริงหรือเท็จขึ้นอยู่กับว่าเพจนั้นมีแถบเลื่อนแนวตั้งหรือไม่

ตัวอย่างเช่น:

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

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


1

เพียงแค่เปรียบเทียบความกว้างขององค์ประกอบรูทเอกสาร (เช่นองค์ประกอบ html) กับส่วนด้านในของหน้าต่าง:

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

หากคุณต้องการทราบความกว้างของแถบเลื่อน:

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

0

โซลูชันอื่น ๆ ใช้ไม่ได้กับหนึ่งในโครงการของฉันและฉันสิ้นสุดการตรวจสอบคุณสมบัติ css ล้น

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

แต่จะใช้งานได้ก็ต่อเมื่อแถบเลื่อนปรากฏหายไปโดยการเปลี่ยนเสาจะไม่ทำงานหากเนื้อหาเท่ากันหรือเล็กกว่าหน้าต่าง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.