HTML 요소에 스크롤바가 있는지 확인


113

요소에 스크롤 막대가 있는지 확인하는 가장 빠른 방법은 무엇입니까?

물론 한 가지는 요소가 뷰포트보다 큰지 확인하는 것입니다. 다음 두 값을 확인하면 쉽게 수행 할 수 있습니다.

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

하지만 그렇다고 스크롤바도 있다는 의미는 아닙니다 (실제로 사람이 스크롤 할 수 있음).

질문

1 크로스 브라우저와 2 자바 스크립트 에서 스크롤바를 확인하는 방법은 ( jQuery아닌 것처럼 ) 어떻게해야합니까?

Javascript 전용, 가능한 한 작은 오버 헤드가 필요하기 때문에 매우 빠른 jQuery 선택기 필터를 작성하고 싶습니다.

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

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

overflow스타일 설정 을 확인해야한다고 생각 하지만 크로스 브라우저 방식으로 어떻게 수행합니까?

추가 편집

overflow스타일 설정 뿐만 아니라 . 요소에 스크롤바가 있는지 확인하는 것은 보이는 것만 큼 간단하지 않습니다. 위에서 작성한 첫 번째 수식은 요소에 테두리가 없을 때 잘 작동하지만 테두리가있는 경우 (특히 테두리가 상당한 너비 인 경우) offset차원이 scroll차원 보다 클 수 있지만 요소는 여전히 스크롤 할 수 있습니다. offset요소의 실제 스크롤 가능한 뷰포트를 가져 와서이를 scroll차원 과 비교하려면 실제로 차원에서 테두리를 빼야 합니다.

향후 참조를 위해

:scrollablejQuery 선택기 필터는 내 .scrollintoview()jQuery 플러그인에 포함되어 있습니다. 누군가 필요한 경우 내 블로그 게시물 에서 완전한 코드를 찾을 수 있습니다 . 실제 솔루션을 제공하지는 못했지만 Soumya의 코드는 문제를 해결하는 데 크게 도움이되었습니다. 그것은 나를 올바른 방향으로 가리 켰습니다.

답변:


118

몇 주 전에 어딘가에서 이것을 발견했습니다. 그것은 나를 위해 일했습니다.

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
분명히 간단한 예가 있습니다. 컨테이너가 overflow:hidden설정되어 있다면 어떨까요? 초과 콘텐츠가 있지만 여전히 스크롤 할 수 없습니다. 문제는보기만큼 간단하지 않습니다.
Robert Koritnik

7
이것은 허용되는 해결책이 아닐 수도 있지만 저에게는 효과적이었습니다. 숨겨진 경우 스크롤하는 이유를 잘 모르겠습니다.
vol7ron

이것은 허용되는 해결책이 아닐 수도 있지만 저에게는 효과적이었습니다. Robert는 이러한 경우에 대해 CSS 오버플로 속성을 가져와 해당 사례를 테스트 할 수 없었 div.scrollHeight>div.clientHeight && !(div.style.overflow && div.style.overflow == 'hidden')습니까 (예 :) ?
vol7ron 2011 년

7
이것은 많은 경우에 실패합니다. 요소에 오버플로가있는 경우 : visible; 너비 : 200px; 너비가 500px 인 자식이 있고 요소에 스크롤 막대가 없지만 scrollWidth가 500px이고 clientWidth가 200px입니다.
Joseph Lennox 2014 년

1
오버플로가 표시되거나 숨겨져 있으면 일반적으로 스크롤바가 없습니다.
Hubert Grzeskowiak

16

시험:

수직 스크롤바 용

el.scrollHeight> el.clientHeight

수평 스크롤바 용

el.scrollWidth> el.clientWidth

나는 이것이 IE8과 Firefox 3.6 이상에서 작동한다는 것을 알고 있습니다.


2
나는 이것이 특정 요소가 보이는 것보다 더 크다는 것을 알려주지 만 이것이 스크롤바를 표시한다는 것을 의미하지는 않는다는 것을 예라고 지적했습니다. 또한 가질 수 있으며 overflow:hidden더 이상 스크롤 할 수 없습니다.
Robert Koritnik

1
그리고 clientHeight / clientWidth 값으로 확인하는 것은 좋은 결과를 제공하지 않습니다. 요소도이 측정에 포함되지 않은 테두리를 가질 수 있기 때문입니다. 내 공식을 확인하십시오. 당신보다 잘 작동합니다.
Robert Koritnik

clientHeight / clientWidth 대신 스크롤바를 확인하기 위해 offsetHeight / offsetWidth를 사용하는 것은 사실입니다. 지적 해 주셔서 감사합니다.
Gary

@RobertKoritnik-특정 요소가 있는지 확인하십시오 overflow:hidden. 가장 간단하기 때문에 내 의견으로는 여전히 정답입니다.
vsync 2014 년

14

이 보일 수 있습니다 (또는 일) 조금 hackish,하지만 당신은 테스트 할 수 scrollTopscrollLeft특성을.

0보다 크면 스크롤바가있는 것입니다. 0이면 1로 설정하고 다시 테스트하여 결과가 1인지 확인한 다음 다시 0으로 설정합니다.

예 : 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에는 다른 속성이 있다고 생각하므로 잠시 후에 업데이트하겠습니다.

편집 : IE가이 속성을 지원할 수있는 것처럼 보입니다. (지금은 IE를 테스트 할 수 없습니다.)

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


그것은 훨씬 비교할 경우 스크롤바를 확인하기 쉽게 offsetHeight하고 clientHeight. 후자는 스크롤바가있을 때 항상 스크롤바 크기만큼 작습니다.
Robert Koritnik

@Robert : 더 쉬운 지 확실하지 않지만 어떻게 작동하는지 알 수 있습니다. 그런 다음 요소에 overflow:scroll. 물론 onscroll 이벤트가 연결된 경우 내 솔루션에 문제가있을 수 있습니다.
user113716 14:44에

별로. 내 jQuery 플러그인 을 확인하면 실제 스크롤 가능한 조상을 찾아야합니다. 그렇지 않으면 요소를보기로 스크롤 할 수 없습니다.
Robert Koritnik 2011

8
@RobertKoritnik 사실이 아닙니다. 일부 브라우저에는 너비를 줄이지 않는 스크롤바가있을 수 있습니다. 예를 들어 OS X에서. 또는 터치 장치.
daniel.gindi

1
항상 거짓 반환
Fatih Erol

14

또 다른 해결책은 다음과 같습니다.

몇몇 사람들이 지적했듯이, offsetHeight와 scrollHeight를 비교하는 것만으로는 여전히 스크롤바가없는 오버 플로우 숨겨진 요소 등이 다르기 때문에 충분하지 않습니다. 그래서 여기에서는 요소의 계산 된 스타일에서 오버플로가 스크롤인지 자동인지 확인합니다.

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

경우 overflow*입니다 scroll항상 내가 원하는 생각 때문에, 스크롤이있을 것 vertical: overflowY === 'scroll' || overflowY === 'auto' && node.scrollHeight > node.clientHeight등, (즉, 그래서 브래킷을 제거 scroll*client*경우에만 테스트 overflow*입니다 auto). 그렇지 않으면 이것이 가장 올바른 해결책으로 보입니다.
Jake

@Jake 만약 scrollHeight <clientHeight on scroll overflow, 스크롤바는 거기에있을 것이지만 비활성화 될 것입니다 (즉, 요소는 스크롤 할 수 없습니다). 그래서 나는 그것이 응용 프로그램에 달려 있다고 생각합니다. 수정은 상태와 상관없이 스크롤바를 확인하려는 경우에만 유효합니다. 나에게 이것을 생각해 냈을 때 구성 요소에 대한 자동 스크롤을 구현하려고했기 때문에 스크롤 막대를 비활성화하는 것은 쓸모가 없습니다. 이 질문의 경우에도 해당되는 것으로 보입니다 ( "사람이 스크롤해야 함"필요)
lotif

6

파티에 좀 늦었을지도 모르지만 ...

e.offsetWidth 대 e.clientWidth로 스크롤바를 감지 할 수 있다고 생각합니다. 오프셋 너비에는 테두리 및 스크롤바, 패딩 및 너비가 포함됩니다. 클라이언트 너비에는 패딩과 너비가 포함됩니다. 참조하십시오 :

https://developer.mozilla.org/en/DOM/element.offsetWidth (두 번째 이미지) https://developer.mozilla.org/en/DOM/element.clientWidth (두 번째 이미지)

다음 사항을 확인해야합니다.

  1. 요소에 계산 된 / 계단식 / 현재 스타일을 사용하여 자동 / 스크롤 (overflowX / Y 포함)로 설정된 오버플로가 있는지 여부입니다.
  2. 요소에 자동 / 스크롤로 설정된 오버플로가있는 경우. offsetWidth 및 clientWidth를 설정하십시오.
  3. clientWidth가 offsetWidth-오른쪽 테두리 (계산 / 계단식 / 현재 스타일을 통해 다시 발견됨)보다 작 으면 스크롤 막대가있는 것입니다.

수직 (offset / clientHeight)에 대해서도 동일하게 수행하십시오.

IE7은 일부 요소에 대해 clientHeight를 0으로보고하므로 (이유를 확인하지 않았 음) 항상 첫 번째 오버플로 확인이 필요합니다.

도움이 되었기를 바랍니다!


3

스크롤바의 존재를 확인하는 경우 몇 가지 문제가 있습니다. 그 중 하나는 Mac에서는 스크롤바가 표시되지 않아 위의 모든 솔루션이 정확한 답을 제공하지 않는다는 것입니다.

따라서 브라우저의 렌더링이 자주 발생하지 않기 때문에 스크롤을 변경하여 스크롤이 있는지 확인한 다음 다시 설정할 수 있습니다.

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

위의 솔루션 중 어느 것도 나를 위해 (지금까지) 해결되지 않았기 때문에 여기를 엉망으로 만듭니다. Div의 scrollheight를 offsetHeight와 비교하는 데 성공했습니다.

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

지금까지 정확한 비교를 제공하는 것 같습니다. 이것이 합법적인지 누군가 알고 있습니까?


2
나는 당신이 scrollHeight와 clientHeight를 원한다고 생각한다 : stackoverflow.com/questions/4106538/…
rich remer dec

1

들어 IE11 (인터넷 익스플로러 11) 난에 로직을 변경했다 :

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

이것은 IE가 scrollHeight가 스크롤바가 없을 때 clientHeight보다 1 더 크게보고하지만 스크롤바가있을 때 약 9 더 크게보고하기 때문입니다.


0

당신은 프로그래머 경우에 대한 스크롤 존재 알고 싶다면 전체 웹 페이지 와와를 풀 브라우저 지원 이를 사용할 수 있습니다 :

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

window.innerHeight대신 사용 하는 것이 중요합니다 document.body.clientHeight. 일부 모바일 브라우저에서는 clientHeight 가 주소 표시 줄의 크기를 가져 오지 않지만 scrollHeight 가 가져 오므로 잘못된 계산이 발생합니다.


-5

이 답변 중 어느 것도 정확하지 않습니다. 이것을 사용해야합니다 :

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

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

이것은 6 년 전에 받아 들여진 답변에서 복사 / 붙여 넣기를 받았고 무언가를 부울로 바꾸는 데 괄호가 필요하지 않았기 때문에 반대 투표를 받았습니다.
모토

-6

그 안에 100 % 너비의 요소를 추가합니다. 그런 다음 오버플로를 숨김으로 설정합니다. 요소의 계산 된 스타일 (jQ에서)이 변경되면 부모에 스크롤바가있는 것입니다.

편집 : getComputedStyle 과 같은 크로스 브라우저 메서드를 원하는 것 같습니다 . 시험:

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
이미 jQuery를 사용하고 있다면 auto 또는 scroll$(el).css("overflow/overflowX/overflowY") 설정되어 있는지 확인 하고 싶습니다 . 하지만 jQuery 사용을 피하고 싶습니다.
Robert Koritnik

16
CSS 스타일은 요소 스크롤바 있는지 여부를 알려주지 않습니다 . 스크롤바 가질 있는지 여부 만 . 내부 요소의 너비를 결정하는 크로스 브라우저 방법을 찾을 수 있습니까?
Soumya

@ Soumya92 : 스크롤 가능 크기와 실제 크기 사이의 크기 비교는 사소하며 위에서 작성했습니다 ... 지금 확인해야 할 것은 특정 요소의 현재 오버플로 설정뿐입니다.
Robert Koritnik

@ Soumya92 : 그게 바로 제가 필요한 것입니다. 병합을 사용하여 매우 단순화 할 수도 있습니다.computedStyle = el.currentStyle || document.defaultView.getComputedStyle(el, null);
Robert Koritnik

한 가지 더 : 크로스 브라우저는 어떻게 되나요? 이 기능은 어떤 브라우저를 지원합니까?
Robert Koritnik
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.