숨기지 않고 스크롤을 비활성화 하시겠습니까?


198

라이트 박스를 사용하는 동안 부모의 html / body 스크롤 막대를 비활성화하려고합니다. 여기서 주요 단어는 disable 입니다. 나는 그것을 숨기고 싶지 않습니다overflow: hidden; .

그 이유 overflow: hidden는 사이트가 점프하고 스크롤이 있던 영역을 차지하기 때문입니다.

스크롤 막대를 계속 표시하면서 비활성화 할 수 있는지 알고 싶습니다.


1
스크롤이 가능해야합니까? (라이트 박스에 스크롤바가 있습니까?)
Šime Vidas

사이트가 스크롤되었지만 라이트 박스가 열려있는 동안 비활성화하고 싶습니다. 스크롤 막대를 표시하는 동안 비활성화 할 수 있는지 알고 싶습니다. 라이트 박스 나 그 밖의 다른 방법으로 수행 할 필요가 없습니다.
Dejan.S

스크롤 막대가있는 라이트 박스를 사용하는 데 어떤 문제가 있습니까?
manny

1
@Dejan 모든 스크롤 을 비활성화하는 방법을 알고 있기 때문에 -메인 스크롤바를 비활성화 할뿐만 아니라 라이트 박스의 스크롤도 비활성화합니다.
Šime Vidas

1
이 게시물의 답을 다시 편집하지 마십시오. 아래 답변 섹션은 답변입니다. 아래 답변과 다른 질문 에 대한 답변이있는 경우 답변 선택에 고유 한 솔루션을 추가 할 수 있습니다.
intcreator

답변:


172

오버레이 아래의 페이지를 상단에 "고정"할 수있는 경우 오버레이를 열 때 설정할 수 있습니다

body { position: fixed; overflow-y:scroll }

여전히 오른쪽 스크롤 막대가 표시되지만 내용을 스크롤 할 수는 없습니다. 오버레이를 닫으면이 속성을

body { position: static; overflow-y:auto }

스크롤 이벤트를 변경할 필요가 없기 때문에이 방법을 제안했습니다.

최신 정보

document.documentElement.scrollTop레이어를 열기 직전에 자바 스크립트를 통해 속성을 얻는 경우 top본문 요소의 속성 으로 해당 값을 동적으로 할당 할 수 있습니다. 맨 위로 또는 이미 스크롤 한 경우.

CSS

.noscroll { position: fixed; overflow-y:scroll }

JS

$('body').css('top', -(document.documentElement.scrollTop) + 'px')
         .addClass('noscroll');

2
레이아웃이 엉망이지만 수정하면 작동 할 수 있습니다. 나는 이것을 좋아한다 나는 그것을 더 시도 할 것이다
Dejan.S

4
약간 수정하면 작동합니다. 너비를 추가했습니다 : 100 %; 나는 해결책으로 내 질문을 업데이트하지 못했지만 너비를 사용하여를 수정할 수 있습니다 : 100 % ;? 제안 해 주셔서 감사합니다
Dejan.S

3
이유를 모르겠지만이 방법이 더 효과적입니다. $('body').css('top', -($('body').scrollTop()) + 'px').addClass('noscroll');
PDXIII

4
@whitesiroi, 당신이 맞아요. 나는 바이올린을 업데이트했습니다 : jsfiddle.net/evpozdniakov/2m8km9wg 감사합니다!
evpozdniakov

1
솔루션에 대한 주석을 읽는 사람들에게 마지막 바이올린은 두 경우 모두 스크롤 막대 위치를 유지하면서 스크롤 막대를 비활성화하고 다시 활성화하는 솔루션을 제공합니다. 감사!
user1063287

78

선택한 솔루션에 4 가지 추가 사항 :

  1. IE에서 이중 스크롤 막대를 방지하기 위해 본문 대신 HTML에 'noscroll'을 적용하십시오.
  2. 하려면 실제로 스크롤 막대가 있는지 확인 'noscroll'클래스를 추가하기 전에. 그렇지 않으면, 새로운 비 스크롤 스크롤 막대로 사이트가 밀려납니다.
  3. 가능한 모든 scrollTop 을 유지하려면 Fabrizio의 업데이트와 같이 전체 페이지가 맨 위로 돌아 가지 않지만 'noscroll'클래스를 추가하기 전에 값을 가져와야합니다.
  4. 모든 브라우저가 scrollTop을 처리하는 것은 아닙니다 : http://help.dottoro.com/ljnvjiow.php

대부분의 브라우저에서 작동하는 완벽한 솔루션 :

CSS

html.noscroll {
    position: fixed; 
    overflow-y: scroll;
    width: 100%;
}

스크롤 비활성화

if ($(document).height() > $(window).height()) {
     var scrollTop = ($('html').scrollTop()) ? $('html').scrollTop() : $('body').scrollTop(); // Works for Chrome, Firefox, IE...
     $('html').addClass('noscroll').css('top',-scrollTop);         
}

스크롤 사용

var scrollTop = parseInt($('html').css('top'));
$('html').removeClass('noscroll');
$('html,body').scrollTop(-scrollTop);

Fabrizio와 Dejan에게 올바른 트랙을 알려주고 Brodingo에게 이중 스크롤 막대대한 솔루션을 제공해 주셔서 감사 합니다.


1
이것은 데스크탑에서 잘 테스트되었지만 iPhone에서는 독자가 페이지를 스크롤하려고 시도 할 때까지 빈 흰색 화면이 만들어졌습니다. 독자가 페이지와 상호 작용하려고하면 스크롤이 잠긴 상태에서 의도 한 화면이 표시됩니다.
Michael Khalili 2016 년

이 비활성화 된 라이트 박스 이미지의 스크롤에 iPad에서 Fancybox와 함께 완벽하게 작동 afterLoad()하고 afterClose콜백. 이 질문을 검색하는 다른 사람들에게 유용 할 수 있습니다.
Tomanow

"스크롤 사용"파트에서 "스크롤 사용 안함"을 호출 한 후 html 요소에있는 스타일 속성을 제거 할 수 있습니다. 당신은 아닌가요?
Ben

3
jQuery는 네이티브 DOM을 표준화 scrollTop하여 'Disable scroll'코드의 2 행을로 표현할 수 있습니다 $( window ).scrollTop().
바니

나는 이것에 다른 것을 추가해야한다고 생각합니다. OSX의 Chrome에서는 브라우저가 "과도하게 스크롤"되어 스크롤이 탄력적으로 느껴질 수 있습니다. 이 코드를 사용하면 페이지 위 또는 아래의 회색 영역에 있고 스크롤을 사용하지 않는 지점으로 마우스를 가져갑니다. 브라우저 창 위 / 아래에 고정됩니다. 이러한 이유로 음수 스크롤 값에 대한 검사를 추가해야합니다 if (scrollTop < 0) { scrollTop = 0; }. 다음은 disable gist.github.com/jayd3e/2eefbbc571cd1668544b 의 전체 코드입니다 .
JayD3e

34

jQuery가 포함 된 경우 :


비활성화

$.fn.disableScroll = function() {
    window.oldScrollPos = $(window).scrollTop();

    $(window).on('scroll.scrolldisabler',function ( event ) {
       $(window).scrollTop( window.oldScrollPos );
       event.preventDefault();
    });
};

가능하게하다

$.fn.enableScroll = function() {
    $(window).off('scroll.scrolldisabler');
};

용법

//disable
$("#selector").disableScroll();
//enable
$("#selector").enableScroll();

1
이것은 나에게 완벽했습니다. 이전 답변으로 페이지가 튀었습니다.이 페이지는 그렇지 않습니다
Bogdan Tomi

다행 난, 모바일 장치 용으로도 "하는 TouchMove"확인해야 할 수도 있습니다, 환호를 도울 수
CEED

글쎄, 이것은 거의 나를 위해 일했다. Firefox의 Windows (Firefox, Chrome) 및 MacOS에서 놀라운 일을했지만 Chrome 및 Safari의 MacOS와 함께 Windows IE 및 Edge로 이동했습니다. 문제는 더 이상 페이지가 좌우로 점프하는 것이 아니라 스크롤 막대가 위에서 현재 위치로 점프하거나 페이지가 위로 깜빡이는 문제였습니다. 사람이이었다 너무 , 너무 가깝습니다. 어쩌면 우리는 여전히 작동시킬 수 있습니다.
Steven Ventimiglia

이것은 나를 위해 완벽하게 작동했습니다, 감사합니다! 오버레이 메뉴가 페이지 하단에있는 웹 사이트에서 사용하기에 이상적입니다!
SauriolJf

12

나는 OP 야

fcalderan의 답변 덕분에 솔루션을 만들 수있었습니다. 사용 방법을 명확하게하고 매우 중요한 세부 사항을 추가하므로 솔루션을 여기에 둡니다.width: 100%;

이 수업을 추가합니다

body.noscroll
{
    position: fixed; 
    overflow-y: scroll;
    width: 100%;
}

이것은 나를 위해 일했고 Fancyapp를 사용하고있었습니다.


11

이것은 나를 위해 정말 잘 작동했습니다 ....

// disable scrolling
$('body').bind('mousewheel touchmove', lockScroll);

// enable scrolling
$('body').unbind('mousewheel touchmove', lockScroll);


// lock window scrolling
function lockScroll(e) {
    e.preventDefault();
}

스크롤을 잠글 때 결정하는 내용 으로이 두 줄의 코드를 래핑하십시오.

예 :

$('button').on('click', function() {
     $('body').bind('mousewheel touchmove', lockScroll);
});

이것은 그들 중 가장 좋은 답변입니다
Jafo

7

스크롤 이벤트는 비활성화 할 수 없지만 마우스 휠 및 touchmove와 같이 스크롤로 이어지는 관련 동작은 비활성화 할 수 있습니다.

$('body').on('mousewheel touchmove', function(e) {
      e.preventDefault();
});

4

본문의 스크롤 막대를 숨기고 overflow: hidden동시에 여백을 설정하여 내용이 점프하지 않도록 할 수 있습니다.

let marginRightPx = 0;
if(window.getComputedStyle) {
    let bodyStyle = window.getComputedStyle(document.body);
    if(bodyStyle) {
        marginRightPx = parseInt(bodyStyle.marginRight, 10);
    }
}

let scrollbarWidthPx = window.innerWidth - document.body.clientWidth;
Object.assign(document.body.style, {
    overflow: 'hidden',
    marginRight: `${marginRightPx + scrollbarWidthPx}px`
});

그런 다음 비활성화 된 스크롤 막대를 페이지에 추가하여 간격을 채울 수 있습니다.

textarea {
  overflow-y: scroll;
  overflow-x: hidden;
  width: 11px;
  outline: none;
  resize: none;
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  border: 0;
}
<textarea></textarea>

내 라이트 박스 구현을 위해 정확히 이것을했습니다. 지금까지 잘 작동하는 것 같습니다.


1
실제로이 방법이 가장 좋습니다. 매우 간단하고 훌륭하게 작동합니다. 감사!
dericcain

2

이것이 우리가 함께했던 해결책입니다. 오버레이가 열릴 때 스크롤 위치를 저장하고 사용자가 페이지를 스크롤하려고 할 때마다 저장된 위치로 다시 스크롤 한 다음 오버레이가 닫힐 때 리스너를 끄십시오.

IE에서는 약간 어색하지만 Firefox / Chrome의 매력처럼 작동합니다.

var body = $("body"),
  overlay = $("#overlay"),
  overlayShown = false,
  overlayScrollListener = null,
  overlaySavedScrollTop = 0,
  overlaySavedScrollLeft = 0;

function showOverlay() {
  overlayShown = true;

  // Show overlay
  overlay.addClass("overlay-shown");

  // Save scroll position
  overlaySavedScrollTop = body.scrollTop();
  overlaySavedScrollLeft = body.scrollLeft();

  // Listen for scroll event
  overlayScrollListener = body.scroll(function() {
    // Scroll back to saved position
    body.scrollTop(overlaySavedScrollTop);
    body.scrollLeft(overlaySavedScrollLeft);
  });
}

function hideOverlay() {
  overlayShown = false;

  // Hide overlay
  overlay.removeClass("overlay-shown");

  // Turn scroll listener off
  if (overlayScrollListener) {
    overlayScrollListener.off();
    overlayScrollListener = null;
  }
}

// Click toggles overlay
$(window).click(function() {
  if (!overlayShown) {
    showOverlay();
  } else {
    hideOverlay();
  }
});
/* Required */
html, body { margin: 0; padding: 0; height: 100%; background: #fff; }
html { overflow: hidden; }
body { overflow-y: scroll; }

/* Just for looks */
.spacer { height: 300%; background: orange; background: linear-gradient(#ff0, #f0f); }
.overlay { position: fixed; top: 20px; bottom: 20px; left: 20px; right: 20px; z-index: -1; background: #fff; box-shadow: 0 0 5px rgba(0, 0, 0, .3); overflow: auto; }
.overlay .spacer { background: linear-gradient(#88f, #0ff); }
.overlay-shown { z-index: 1; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<h1>Top of page</h1>
<p>Click to toggle overlay. (This is only scrollable when overlay is <em>not</em> open.)</p>
<div class="spacer"></div>
<h1>Bottom of page</h1>
<div id="overlay" class="overlay">
  <h1>Top of overlay</h1>
  <p>Click to toggle overlay. (Containing page is no longer scrollable, but this is.)</p>
  <div class="spacer"></div>
  <h1>Bottom of overlay</h1>
</div>


실제로 작동하지만 스크롤 막대가 그 아래에 있으므로 고정 헤더의 경우 디자인을 오염시킵니다.
레온 윌 렌스

@LeonWillens 무슨 말인지 잘 모르겠습니다. 당신은 고정 된 헤더 아래에 나타나는 오버레이에 대해 우려하는 경우, 당신은 조정해야 z-index의가 .overlay-shown고정 된 헤더보다 클 수 있습니다. (이 코드는 고정 된 헤더가있는 사이트에서 프로덕션 환경에서 실행되며 제대로 작동합니다.)
0b10011

아니요, body태그 의 스크롤 막대에 대해 이야기했습니다 . 어제 코드를 실험했으며 내 페이지 상단에 고정 헤더가 있습니다. body태그 를 통한 스크롤을 처리 하면 스크롤 막대가 고정 헤더 아래에 있습니다.
레온 Willens

1
@ LeonWillens Oops, 프로덕션 에서이 부분을 수정하고 업데이트하는 것을 잊어 버린 것 같습니다. 대신 것 같습니다 $("body"), 우리가 사용하고 있습니다 $(window). z-index: -1오버레이 대신 오버레이 대신 사용 visibility: hidden하거나 유사하게 사용할 수 있습니다 . 참조 jsfiddle.net/8p2gfeha 작동하는지 확인하기 위해 간단한 테스트를 위해. 고정 헤더가 더 이상 스크롤 막대 위에 나타나지 않습니다. 결국 이러한 변경 사항을 답변에 통합하려고 노력할 것입니다.
0b10011

매력처럼 작동합니다! 감사합니다 :)
Leon Willens

1

비슷한 문제가 있습니다. 왼쪽 메뉴가 나타나면 스크롤을 방지합니다. 높이가 100vh로 설정 되 자마자 스크롤바가 사라지고 내용이 오른쪽으로 움직입니다.

따라서 스크롤 막대를 활성화하지 않아도 (창을 전체 높이로 설정하여 실제로 스크롤하지 않도록) 작은 아래쪽 여백을 설정하면 스크롤 막대가 계속 표시됩니다.

body {
    height: 100vh;
    overflow: hidden;
    margin: 0 0 1px;
}

은하지 않습니다 overflow:hidden어떤 영향을에서 마진을 방지?
Koja

0

overflow : hidden을 유지하면서 스크롤 위치를 수동으로 관리 할 수 ​​있습니다.

실제 스크롤 위치 추적을 표시하기 전에 :

var scroll = [$(document).scrollTop(),$(document).scrollLeft()];
//show your lightbox and then reapply scroll position
$(document).scrollTop(scroll[0]).scrollLeft(scroll[1]);

작동해야한다


0

조잡하지만 작동하는 방법은 스크롤을 맨 위로 밀어서 스크롤을 효과적으로 비활성화하는 것입니다.

var _stopScroll = false;
window.onload = function(event) {
    document.onscroll = function(ev) {
        if (_stopScroll) {
            document.body.scrollTop = "0px";
        }
    }
};

라이트 박스를 열면 깃발을 올리고 닫을 때 깃발을 내립니다.

라이브 테스트 사례 .


0

"overflow : hidden"방법을 고수하고 스크롤바 너비와 같은 패딩 오른쪽을 추가하고 싶습니다.

lostsource로 스크롤바 너비 함수를 가져옵니다 .

function getScrollbarWidth() {
    var outer = document.createElement("div");
    outer.style.visibility = "hidden";
    outer.style.width = "100px";
    outer.style.msOverflowStyle = "scrollbar"; // needed for WinJS apps

    document.body.appendChild(outer);

    var widthNoScroll = outer.offsetWidth;
    // force scrollbars
    outer.style.overflow = "scroll";

    // add innerdiv
    var inner = document.createElement("div");
    inner.style.width = "100%";
    outer.appendChild(inner);        

    var widthWithScroll = inner.offsetWidth;

    // remove divs
    outer.parentNode.removeChild(outer);

    return widthNoScroll - widthWithScroll;
}

오버레이를 표시 할 때 html에 "noscroll"클래스를 추가하고 body에 padding-right를 추가하십시오.

$(html).addClass("noscroll");
$(body).css("paddingRight", getScrollbarWidth() + "px");

숨길 때 클래스와 패딩을 제거하십시오.

$(html).removeClass("noscroll");
$(body).css("paddingRight", 0);

noscroll 스타일은 다음과 같습니다.

.noscroll { overflow: hidden; }

position : fixed가있는 요소가있는 경우 해당 요소에도 패딩을 추가해야합니다.


이 솔루션을 사용했습니다. 이중 스크롤 막대 (본문은 '빈', 오버레이 내용은 두 번째)를 피하는 데 도움이되었습니다. 또한 스크롤 막대를 표시하거나 표시하지 않을 수있는 OSX에서도 매우 잘 작동합니다.
Novazembla

0

<div id="lightbox"><body>요소 안에 있으므로 라이트 박스를 스크롤하면 본문도 스크롤됩니다. 해결책은 <body>요소를 100 % 이상 확장하지 않고 다른 div요소 안에 긴 내용을 배치 하고이 div요소에 필요한 경우 스크롤 막대를 추가하는 것 입니다 overflow: auto.

html {
  height: 100%
}
body {
  margin: 0;
  height: 100%
}
#content {
  height: 100%;
  overflow: auto;
}
#lightbox {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
}
<html>
  <body>
    <div id="content">much content</div>
    <div id="lightbox">lightbox<div>
  </body>
</html>

이제 body본체가 화면 높이의 100 %를 넘지 않기 때문에 라이트 박스를 스크롤해도 효과가 없습니다.


0

모든 모달 / 라이트 박스 자바 스크립트 기반 시스템은 모달 / 라이트 박스를 html 태그 또는 본문 태그에 표시 할 때 오버플로를 사용합니다.

라이트 박스가 표시되면 js가 html 또는 body 태그에 숨겨진 오버플로를 푸시합니다. 라이트 박스가 숨겨지면 일부는 숨겨져있는 다른 것을 제거합니다. HTML 또는 본문 태그에서 오버플로 자동을 푸시합니다.

Mac에서 작업하는 개발자에게는 스크롤 막대의 문제가 표시되지 않습니다.

스크롤 바 제거 모드에서 미끄러지는 내용을 보지 않으려면 숨겨진 항목을 설정하지 않은 상태로 바꾸십시오.

라이트 박스 열기 / 표시 :

<html style="overflow: unset;"></html>

라이트 박스 닫기 / 숨기기 :

<html style="overflow: auto;"></html>

0

오버레이 아래의 페이지를 상단에 "고정"할 수있는 경우 오버레이를 열 때 설정할 수 있습니다

.disableScroll { position: fixed; overflow-y:scroll }

이 클래스를 스크롤 가능 본문에 제공하면 여전히 오른쪽 스크롤 막대가 표시되지만 내용은 스크롤 가능하지 않습니다.

페이지의 위치를 ​​유지하려면 jquery 에서이 작업을 수행하십시오.

$('body').css('top', - ($(window).scrollTop()) + 'px').addClass('disableScroll');

오버레이를 닫으면이 속성을

var top = $('body').position().top;
$('body').removeClass('disableScroll').css('top', 0).scrollTop(Math.abs(top));

스크롤 이벤트를 변경할 필요가 없기 때문에이 방법을 제안했습니다.


0

스크롤 위치를 저장하고 스크롤을 활성화하면 복원하여 뷰포트가 상단으로 점프하는 것을 중지합니다.

CSS

.no-scroll{
  position: fixed; 
  width:100%;
  min-height:100vh;
  top:0;
  left:0;
  overflow-y:scroll!important;
}

JS

var scrollTopPostion = 0;

function scroll_pause(){
  scrollTopPostion = $(window).scrollTop();
  $("body").addClass("no-scroll").css({"top":-1*scrollTopPostion+"px"});
}

function scroll_resume(){
  $("body").removeClass("no-scroll").removeAttr("style");
  $(window).scrollTop(scrollTopPostion);
}

이제 필요한 것은 함수를 호출하는 것입니다

$(document).on("click","#DISABLEelementID",function(){
   scroll_pause();
});

$(document).on("click","#ENABLEelementID",function(){
   scroll_resume();
});

-1

Javascript로 할 수 있습니다 :

// Classic JS
window.onscroll = function(ev) {
  ev.preventDefault();
}

// jQuery
$(window).scroll(function(ev) {
  ev.preventDefault();
}

라이트 박스가 닫히면 사용 중지합니다.

그러나 라이트 박스에 스크롤 막대가 있으면 열려있는 동안 스크롤 할 수 없습니다. 때문입니다 window모두 포함 body하고 #lightbox. 따라서 다음과 같은 아키텍처를 사용해야합니다.

<body>
  <div id="global"></div>
  <div id="lightbox"></div>
</body>

그런 다음에 onscroll이벤트 만 적용하십시오 #global.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.