라이트 박스를 사용하는 동안 부모의 html / body 스크롤 막대를 비활성화하려고합니다. 여기서 주요 단어는 disable 입니다. 나는 그것을 숨기고 싶지 않습니다overflow: hidden;
.
그 이유 overflow: hidden
는 사이트가 점프하고 스크롤이 있던 영역을 차지하기 때문입니다.
스크롤 막대를 계속 표시하면서 비활성화 할 수 있는지 알고 싶습니다.
라이트 박스를 사용하는 동안 부모의 html / body 스크롤 막대를 비활성화하려고합니다. 여기서 주요 단어는 disable 입니다. 나는 그것을 숨기고 싶지 않습니다overflow: hidden;
.
그 이유 overflow: hidden
는 사이트가 점프하고 스크롤이 있던 영역을 차지하기 때문입니다.
스크롤 막대를 계속 표시하면서 비활성화 할 수 있는지 알고 싶습니다.
답변:
오버레이 아래의 페이지를 상단에 "고정"할 수있는 경우 오버레이를 열 때 설정할 수 있습니다
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');
$('body').css('top', -($('body').scrollTop()) + 'px').addClass('noscroll');
선택한 솔루션에 4 가지 추가 사항 :
대부분의 브라우저에서 작동하는 완벽한 솔루션 :
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에게 이중 스크롤 막대 에 대한 솔루션을 제공해 주셔서 감사 합니다.
afterLoad()
하고 afterClose
콜백. 이 질문을 검색하는 다른 사람들에게 유용 할 수 있습니다.
scrollTop
하여 'Disable scroll'코드의 2 행을로 표현할 수 있습니다 $( window ).scrollTop()
.
if (scrollTop < 0) { scrollTop = 0; }
. 다음은 disable gist.github.com/jayd3e/2eefbbc571cd1668544b 의 전체 코드입니다 .
$.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();
이것은 나를 위해 정말 잘 작동했습니다 ....
// 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);
});
본문의 스크롤 막대를 숨기고 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>
내 라이트 박스 구현을 위해 정확히 이것을했습니다. 지금까지 잘 작동하는 것 같습니다.
이것이 우리가 함께했던 해결책입니다. 오버레이가 열릴 때 스크롤 위치를 저장하고 사용자가 페이지를 스크롤하려고 할 때마다 저장된 위치로 다시 스크롤 한 다음 오버레이가 닫힐 때 리스너를 끄십시오.
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>
z-index
의가 .overlay-shown
고정 된 헤더보다 클 수 있습니다. (이 코드는 고정 된 헤더가있는 사이트에서 프로덕션 환경에서 실행되며 제대로 작동합니다.)
body
태그 의 스크롤 막대에 대해 이야기했습니다 . 어제 코드를 실험했으며 내 페이지 상단에 고정 헤더가 있습니다. body
태그 를 통한 스크롤을 처리 하면 스크롤 막대가 고정 헤더 아래에 있습니다.
$("body")
, 우리가 사용하고 있습니다 $(window)
. z-index: -1
오버레이 대신 오버레이 대신 사용 visibility: hidden
하거나 유사하게 사용할 수 있습니다 . 참조 jsfiddle.net/8p2gfeha 작동하는지 확인하기 위해 간단한 테스트를 위해. 고정 헤더가 더 이상 스크롤 막대 위에 나타나지 않습니다. 결국 이러한 변경 사항을 답변에 통합하려고 노력할 것입니다.
조잡하지만 작동하는 방법은 스크롤을 맨 위로 밀어서 스크롤을 효과적으로 비활성화하는 것입니다.
var _stopScroll = false;
window.onload = function(event) {
document.onscroll = function(ev) {
if (_stopScroll) {
document.body.scrollTop = "0px";
}
}
};
라이트 박스를 열면 깃발을 올리고 닫을 때 깃발을 내립니다.
"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가있는 요소가있는 경우 해당 요소에도 패딩을 추가해야합니다.
<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 %를 넘지 않기 때문에 라이트 박스를 스크롤해도 효과가 없습니다.
모든 모달 / 라이트 박스 자바 스크립트 기반 시스템은 모달 / 라이트 박스를 html 태그 또는 본문 태그에 표시 할 때 오버플로를 사용합니다.
라이트 박스가 표시되면 js가 html 또는 body 태그에 숨겨진 오버플로를 푸시합니다. 라이트 박스가 숨겨지면 일부는 숨겨져있는 다른 것을 제거합니다. HTML 또는 본문 태그에서 오버플로 자동을 푸시합니다.
Mac에서 작업하는 개발자에게는 스크롤 막대의 문제가 표시되지 않습니다.
스크롤 바 제거 모드에서 미끄러지는 내용을 보지 않으려면 숨겨진 항목을 설정하지 않은 상태로 바꾸십시오.
라이트 박스 열기 / 표시 :
<html style="overflow: unset;"></html>
라이트 박스 닫기 / 숨기기 :
<html style="overflow: auto;"></html>
오버레이 아래의 페이지를 상단에 "고정"할 수있는 경우 오버레이를 열 때 설정할 수 있습니다
.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));
스크롤 이벤트를 변경할 필요가 없기 때문에이 방법을 제안했습니다.
스크롤 위치를 저장하고 스크롤을 활성화하면 복원하여 뷰포트가 상단으로 점프하는 것을 중지합니다.
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();
});
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
.