Phát hiện xem một trang có thanh cuộn dọc hay không?


121

Tôi chỉ muốn một số JQ / JS đơn giản để kiểm tra xem trang / cửa sổ hiện tại (không phải một phần tử cụ thể) có thanh cuộn dọc hay không.

Googling cung cấp cho tôi những thứ có vẻ quá phức tạp chỉ đối với tính năng cơ bản này.

Điều này có thể giải quyết như thế nào?

Câu trả lời:


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 nhưng vì lý do chính xác, điều này chỉ kiểm tra xem nội dung có mở rộng hơn chế độ xem hay không. Nếu thuộc overflowtính của bodyđược đặt hiddenở đâu đó dọc theo dòng, nó sẽ không hoạt động. Tuy nhiên, việc đặt ẩn trên một cơ thể là cực kỳ hiếm.
Pekka

4
Điều này không hoạt động nếu chiều cao nội dung khớp với chiều cao cửa sổ, trong trường hợp này nếu chiều cao tài liệu khớp chính xác với chế độ xem thì một thanh cuộn ngang sẽ được thêm vào . Nó sẽ buộc vert. thanh cuộn nhưng chiều cao doc / body / window giống nhau; nó sẽ KHÔNG cảnh báo "thanh cuộn dọc" ngay cả khi có một.
Ngừng vu khống Monica Cellio vào

2
Tôi chỉ nghĩ rằng tôi sẽ đề cập đến việc tôi phải sử dụng $(document)thay vì $("body"), điều này đã hiệu quả với tôi khi body thì không (tôi có một vùng chứa được định vị tuyệt đối với tỷ lệ khung hình trên chiều rộng / chiều cao)
am_

1
Tôi có trang báo cáo trên trình duyệt Chrome, nơi ban đầu nó hiển thị một thanh cuộn và biến mất trong vài mili giây, giống như một hành vi của trình duyệt vì tôi không lập trình nó. Vì vậy chức năng này trở lại đúng luôn trong trường hợp của tôi ..
Dush

@TiuTalk cho tôi $ ("body"). Height () & $ (window) .height () cho cùng một giá trị, thay vào đó tôi sử dụng $ (document) .height ()> $ (window) .height () nó hoạt động cho tôi.
SarangK

77

thử cái này:

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

Tuy nhiên, điều này sẽ chỉ cho bạn biết liệu chiều cao của cuộn dọc có lớn hơn chiều cao của nội dung có thể xem hay không. CáchasVScroll biến sẽ chứa đúng hay sai.

Nếu bạn cần kiểm tra kỹ lưỡng hơn, hãy thêm thông tin sau vào đoạn mã trên:

// 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 Tuyệt vời! Và với phong cách tính toán cần thiết (đó là điểm mà tại đó tôi đã quyết định không tham gia với câu hỏi này;)
Pekka

lol yeah Tôi đang tranh luận xem có nên nỗ lực thêm để viết nó hay không vì trong nhiều trường hợp, nó không cần thiết.
Andy E

1
Điều này dẫn đến hasVScroll là true bất cứ khi nào trànY 'hiển thị' bất kể scrollHeight có lớn hơn clientHeight hay không. Có thể bạn muốn nói cStyle.overflow === 'scroll'?
BT

5
Đoạn mã trên không hoạt động. Trình duyệt: Chrome 56. Url: news.greylock.com/…
Sebastien Lorber

1
@BT cStyle.overflow == "visible" có thể hiển thị thanh cuộn khi phần tử là document.body. Nhưng nó phải là (hasVScroll && cStyle.overflow == "display" && element.nodeName == "BODY"). Thêm vào đó, nó cần phải kiểm tra cStyle.overflow === 'scroll'như bạn đã chỉ ra.
mseifert

44

Tôi đã thử câu trả lời trước và có vẻ như không hoạt động. $ ("Body"). Height () không nhất thiết đại diện cho toàn bộ chiều cao html.

Tôi đã sửa giải pháp như sau:

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

Hãy mang câu hỏi này trở lại từ cõi chết;) Có một lý do Google không cung cấp cho bạn một giải pháp đơn giản. Các trường hợp đặc biệt và các điều kỳ quặc của trình duyệt ảnh hưởng đến việc tính toán, và nó không hề tầm thường như nó tưởng tượng.

Thật không may, có vấn đề với các giải pháp được nêu ở đây cho đến nay. Tôi không có ý chê bai chúng - chúng là những điểm khởi đầu tuyệt vời và chạm đến tất cả các thuộc tính quan trọng cần thiết cho một cách tiếp cận mạnh mẽ hơn. Nhưng tôi không khuyên bạn nên sao chép và dán mã từ bất kỳ câu trả lời nào khác vì

  • họ không nắm bắt được tác động của nội dung được định vị theo cách đáng tin cậy trên nhiều trình duyệt. Các câu trả lời dựa trên kích thước nội dung hoàn toàn bỏ lỡ điều này (nội dung không phải là phần cha bù đắp của nội dung đó trừ khi nó được định vị chính nó). Và những câu trả lời đó đang kiểm tra $( document ).width().height()trở thành con mồi cho sự phát hiện lỗi của jQuery về kích thước tài liệu .
  • Dựa vào window.innerWidth , nếu trình duyệt hỗ trợ, làm cho mã của bạn không phát hiện được thanh cuộn trong trình duyệt trên thiết bị di động, nơi chiều rộng của thanh cuộn thường là 0. Chúng chỉ được hiển thị tạm thời dưới dạng lớp phủ và không chiếm dung lượng trong tài liệu . Phóng to trên di động cũng trở thành một vấn đề theo cách đó (câu chuyện dài).
  • Việc phát hiện có thể bị loại bỏ khi mọi người đặt rõ ràng phần tràn của cả phần tử htmlbodythành các giá trị không mặc định (những gì xảy ra sau đó có một chút liên quan - xem mô tả này ).
  • Trong hầu hết các câu trả lời, phần đệm nội dung, đường viền hoặc lề không được phát hiện và làm sai lệch kết quả.

Tôi đã dành nhiều thời gian hơn những gì tôi tưởng tượng để tìm ra một giải pháp "hiệu quả" (ho). Thuật toán tôi đưa ra hiện là một phần của plugin, jQuery.isInView , cho thấy một .hasScrollbarphương pháp . Hãy xem nguồn nếu bạn muốn.

Trong trường hợp bạn có toàn quyền kiểm soát trang và không phải xử lý CSS không xác định, việc sử dụng plugin có thể là quá mức cần thiết - sau cùng, bạn biết trường hợp nào áp dụng và trường hợp nào không. Tuy nhiên, nếu bạn cần kết quả đáng tin cậy trong một môi trường không xác định, thì tôi không nghĩ các giải pháp được nêu ở đây là đủ. Tốt hơn hết bạn nên sử dụng một plugin đã được thử nghiệm tốt - của tôi hoặc bất kỳ ai cũng được.


Cảm ơn. Khá là phức tạp! Nếu bạn không muốn / cần phải tương thích ngược, có lẽ có một giải pháp dễ dàng hơn cho các trình duyệt html5? Ý tôi là có lẽ những người viết mã trình duyệt / w3c đã đủ tốt để chỉ cho chúng tôi biết liệu có thanh cuộn hay không trên một phần tử? ;-)
Leo

1
@Leo Không phải tôi biết. Vâng, có một window.scrollbarsđối tượng có một thuộc tính duy nhất visible,. Nghe có vẻ hứa hẹn nhưng không phải vậy. Nó không được hỗ trợ trong IE, kể cả IE11. Và nó chỉ cho bạn biết rằng có một thanh cuộn - nhưng không phải cái nào. Xem trang thử nghiệm tại đây .
hashchange

Cảm ơn @hashchange. Nghe có vẻ ngu ngốc đến khó tin khi nó chỉ cho biết có thanh cuộn nào không nên tôi đoán nó chỉ là một loại thử nghiệm nào đó. Một chút hứa hẹn mặc dù. ;-)
Leo

1
@BT Ok, tuyệt vời. Bây giờ để tôi dẫn bạn đến lối vào của lỗ thỏ;) Đây là bản demo mà nội dung không đủ để lấp đầy cửa sổ. Tính năng phát hiện của bạn hoạt động trong FF nhưng không thành công trong Chrome. Và đây là một bản demo khác , nơi một phần tử được định vị được đặt ở phía dưới trang. Tính năng phát hiện của bạn hoạt động trong Chrome nhưng không thành công trong FF.
hashchange

1
@BT Và tôi đoán chúng ta có thể mắc phải một loạt các chế độ thất bại kỳ lạ khi chúng ta bắt đầu chơi với cài đặt tràn vì hành vi của chúng hơi kỳ quặc , nhưng tôi đã dừng lại ngay tại đó.
hashchange

15

Điều này đã làm việc cho tôi:

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

Đối với cơ thể, chỉ cần sử dụng hasVerticalScroll().


Đây là câu trả lời duy nhất trong chủ đề này hoạt động trên Chrome của tôi
Nertan Lucian

clientHeightlà tốt hơn offsetHeightở đây. Nếu không, bạn có thể có một đường viền dày và trả lại không có thanh cuộn khi có.
theicfire


3

Kỳ lạ là không có giải pháp nào trong số này cho bạn biết liệu một trang có thanh cuộn dọc hay không.

window.innerWidth - document.body.clientWidthsẽ cung cấp cho bạn chiều rộng của thanh cuộn. Điều này sẽ hoạt động trong bất kỳ IE9 + nào (không được thử nghiệm trong các trình duyệt thấp hơn). (Hoặc để trả lời đúng câu hỏi,!!(window.innerWidth - document.body.clientWidth)

Tại sao? Giả sử bạn có một trang mà nội dung cao hơn chiều cao cửa sổ và người dùng có thể cuộn lên / xuống. Nếu bạn đang sử dụng Chrome trên máy Mac mà không cắm chuột, người dùng sẽ không thấy thanh cuộn. Cắm chuột vào và một thanh cuộn sẽ xuất hiện. (Lưu ý rằng hành vi này có thể được ghi đè, nhưng đó là AFAIK mặc định).


Giải thích về hành vi Chrome-Mouse đã giúp tôi tìm ra những gì tôi nghĩ là hành vi không nhất quán. Cảm ơn!
bắt đầu từ

2

Tôi đã tìm thấy dung dịch vanila

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
Không hoạt động trong IE 11. window.innerWidth & document.documentElement.clientWidth luôn giống nhau.
NLV

Đã sửa nó. Chức năng tương tự này cũng hoạt động cho IE 11. Vấn đề là thế này - stackoverflow.com/questions/17045132/…
NLV

Tôi đã thử nghiệm điều này trong Chrome 65 và nó hoạt động. Nhưng khi tôi điều chỉnh nó cho thanh cuộn ngang, kết quả thật kỳ lạ: Nếu cả thanh cuộn ngang và dọc đều được hiển thị thì window.innerWidth > document.documentElement.clientWidthđúng, nhưng window.innerHeight > document.documentElement.clientHeightkhông phải. Có vẻ như nó là một cách khác trong trường hợp này. Tôi không phải là nhà phát triển JS, tôi chỉ cần nó cho các bài kiểm tra Selenium. Tôi biết ơn vì những gợi ý.
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>

Cái này sẽ cho bạn biết nếu bạn có thanh cuộn hay không. Tôi đã bao gồm một số thông tin có thể giúp gỡ lỗi, thông tin này sẽ hiển thị dưới dạng cảnh báo JavaScript.

Đặt thẻ này vào thẻ script, sau thẻ đóng nội dung.


1

Tôi đã viết một phiên bản cập nhật của câu trả lời của 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()
}

Hàm trả về true hoặc false tùy thuộc vào trang có thanh cuộn dọc hay không.

Ví dụ:

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

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

1

tôi sử dụng

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

1

Đơn giản chỉ cần so sánh chiều rộng của phần tử gốc tài liệu (tức là phần tử html) với phần bên trong của cửa sổ:

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

Nếu bạn cũng cần biết chiều rộng thanh cuộn:

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

0

Các giải pháp khác không hoạt động trong một trong các dự án của tôi và tôi đã kết thúc việc kiểm tra thuộc tính css tràn

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

nhưng nó sẽ chỉ hoạt động nếu thanh cuộn xuất hiện biến mất bằng cách thay đổi giá đỡ, nó sẽ không hoạt động nếu nội dung bằng hoặc nhỏ hơn cửa sổ.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.