일시적으로 스크롤을 비활성화하는 방법은 무엇입니까?


434

scrollTo jQuery 플러그인을 사용하고 있으며 Javascript를 통해 window 요소에서 일시적으로 스크롤을 비활성화 할 수 있는지 알고 싶습니다. 스크롤을 사용하지 않으려는 이유는 scrollTo가 애니메이션을 적용하는 동안 스크롤 할 때 실제로 추악하기 때문입니다.)

물론 $("body").css("overflow", "hidden");애니메이션을 멈출 때 a를 수행 한 다음 자동으로 되돌릴 수 있지만 스크롤 막대가 여전히 보이지만 비활성화되어 있으면 더 좋습니다.


12
여전히 표시되는 경우 사용자는 작동해야한다고 생각하도록 훈련됩니다. 복용량이 이동하지 않거나 복용량이 응답하지 않으면 페이지 작동 방식에 대한 사용자의 정신 모델이 깨져 혼란을 초래합니다. 애니메이션을 중지하는 것과 같이 애니메이션을 사용하는 동안 스크롤을 처리하는 더 좋은 방법을 찾을 수 있습니다.
Marcus Whybrow

답변:


730

scroll이벤트는 취소 할 수 없습니다. 그러나 다음 상호 작용 이벤트 를 취소 하여 이를 수행 할 수 있습니다.
마우스 터치 스크롤단추 관련된 과 .

[ 실무 데모 ]

// left: 37, up: 38, right: 39, down: 40,
// spacebar: 32, pageup: 33, pagedown: 34, end: 35, home: 36
var keys = {37: 1, 38: 1, 39: 1, 40: 1};

function preventDefault(e) {
  e.preventDefault();
}

function preventDefaultForScrollKeys(e) {
  if (keys[e.keyCode]) {
    preventDefault(e);
    return false;
  }
}

// modern Chrome requires { passive: false } when adding event
var supportsPassive = false;
try {
  window.addEventListener("test", null, Object.defineProperty({}, 'passive', {
    get: function () { supportsPassive = true; } 
  }));
} catch(e) {}

var wheelOpt = supportsPassive ? { passive: false } : false;
var wheelEvent = 'onwheel' in document.createElement('div') ? 'wheel' : 'mousewheel';

// call this to Disable
function disableScroll() {
  window.addEventListener('DOMMouseScroll', preventDefault, false); // older FF
  window.addEventListener(wheelEvent, preventDefault, wheelOpt); // modern desktop
  window.addEventListener('touchmove', preventDefault, wheelOpt); // mobile
  window.addEventListener('keydown', preventDefaultForScrollKeys, false);
}

// call this to Enable
function enableScroll() {
  window.removeEventListener('DOMMouseScroll', preventDefault, false);
  window.removeEventListener(wheelEvent, preventDefault, wheelOpt); 
  window.removeEventListener('touchmove', preventDefault, wheelOpt);
  window.removeEventListener('keydown', preventDefaultForScrollKeys, false);
}

업데이트 : 패시브 리스너가있는 고정 Chrome 데스크톱 및 최신 모바일 브라우저


114
이 함정에 빠진 다른 개발자를위한 팁 : 다른 jQuery에서 스크롤을 중지하려고 시도하는 모든 'e.stopPropagation ()'호출을 제거하십시오. 작동하지 않을뿐만 아니라 이벤트 가이 코드로 버블 링되는 것을 방지 작동합니다. 바라건대 내 낭비 30 분 : 다른 사람의 시간을 저장 도움이 될 것입니다
더크 반 베르겐

4
비활성화 된 키 배열에 32 (공백)를 추가 할 수 있습니다 (코드 주석에 표시).
gblazex 2016 년

14
나는 항상처럼 스크롤 할 수 있습니다 : 중간 버튼을 누르고 마우스를 이동 ... 따라서이 트릭은 나 같은 사용자에게 영향을 미치지 않습니다;)
Denis V

11
스크롤바가 비활성화되어 있지 않습니다.
verism

8
Chrome에서는 더 이상 작동하지 않습니다
PerrierCitror

427

본문에 클래스를 추가하여 간단하게 수행하십시오.

.stop-scrolling {
  height: 100%;
  overflow: hidden;
}

클래스를 추가 한 다음 IE, FF, Safari 및 Chrome에서 테스트 한 스크롤을 다시 활성화하려는 경우 제거하십시오.

$('body').addClass('stop-scrolling')

내용은 모바일 장치 , 당신은 처리해야합니다 touchmove이벤트를 :

$('body').bind('touchmove', function(e){e.preventDefault()})

스크롤을 다시 활성화하려면 바인딩을 해제하십시오. iOS6 및 Android 2.3.3에서 테스트

$('body').unbind('touchmove')

4
알았다! touchmove에서와 같이 이벤트 를 처리해야합니다 $('body').bind('touchmove', function(e){e.preventDefault()}). 이 모바일 솔루션을 포함하도록이 답변을 편집했습니다.
MusikAnimal

3
시원합니다. 내부 스크롤이 터치 장치의 모달에서 작동하는지 확인해야합니다. 모달 바로 아래에서 오버레이를 수행하고 바디 대신 오버레이에서 기본 터치 이동을 방지 할 수 있습니다.
hallodom

63
이 솔루션은 작동하지만 페이지의 맨 위로 스크롤하면 바람직하지 않은 효과가 있습니다.
Matt

3
내 선택자가 다음과 같은 경우를 제외하고는 효과가 없었습니다$('body,html')
PickYourPoison

22
이 솔루션은 작동하지만이 클래스를 바디에 적용 할 때 스크롤 막대가 사라지고 '범프'효과 (창 os 아래)를 만듭니다 (예
Georgio

57

이를 수행하는 가장 기본적인 방법은 다음과 같습니다.

window.onscroll = function () { window.scrollTo(0, 0); };

IE6에서는 다소 까다 롭습니다.


14
스크롤을 시도 할 때 기본값으로 스냅하는 것과 같이 실제로 비활성화하는 것은 아닙니다.
Marcus Whybrow

11
@Marcus 취소 할 수없는 이벤트가 발생하면 좋습니다.
sdleihssirhc

3
실제로 비활성화하지는 않지만 시뮬레이트하고 나에게 충분합니다.
Chris Bier

11
IMHO-최고의 답변입니다. 또한로 고정 할 필요는 없으며 (0, 0)현재 스크롤 위치 만 사용하면됩니다.
YemSalat

4
하지만 어떻게 다시 활성화 할 수 있습니까?
Cybernetic

41

다음 솔루션은 기본이지만 순수한 JavaScript입니다 (jQuery 없음).

function disableScrolling(){
    var x=window.scrollX;
    var y=window.scrollY;
    window.onscroll=function(){window.scrollTo(x, y);};
}

function enableScrolling(){
    window.onscroll=function(){};
}

3
Safari 7.1 및 IE 11에서 뛰어납니다. 최신 Chrome, Firefox, Opera ok.
Timo Kähkönen 2014

최신 Chrome에서는 여전히 조금
어려워

잘 작동, 사파리, 크롬,하지만 IE에서
깜박임

이 솔루션이 아닌 일부 브라우저에서 작동하는 경우, 그 브라우저의 문제
오토 Shavadze

다른 답변에서 언급했듯이 scroll-behavior: smooth이것을 질식시킵니다. 또한, 나는 그것이 브라우저의 결함이라고 말하는 Oto에 동의하지 않습니다. 당신은 기본적으로 실제로 비동기 일 때 어떤 일이 즉시 일어날 것이라고 가정합니다
Matt Fletcher

25

이 솔루션은 사용자가 맨 위로 이동하는 것과 달리 스크롤이 비활성화 된 상태에서 현재 스크롤 위치를 유지합니다.

galambalaz의 답변을 기반으로 하지만 터치 장치를 지원하며 jquery 플러그인 래퍼를 사용하여 단일 객체로 리팩토링했습니다.

여기 데모.

여기 github에서.

/**
 * $.disablescroll
 * Author: Josh Harrison - aloof.co
 *
 * Disables scroll events from mousewheels, touchmoves and keypresses.
 * Use while jQuery is animating the scroll position for a guaranteed super-smooth ride!
 */

;(function($) {

    "use strict";

    var instance, proto;

    function UserScrollDisabler($container, options) {
        // spacebar: 32, pageup: 33, pagedown: 34, end: 35, home: 36
        // left: 37, up: 38, right: 39, down: 40
        this.opts = $.extend({
            handleKeys : true,
            scrollEventKeys : [32, 33, 34, 35, 36, 37, 38, 39, 40]
        }, options);

        this.$container = $container;
        this.$document = $(document);
        this.lockToScrollPos = [0, 0];

        this.disable();
    }

    proto = UserScrollDisabler.prototype;

    proto.disable = function() {
        var t = this;

        t.lockToScrollPos = [
            t.$container.scrollLeft(),
            t.$container.scrollTop()
        ];

        t.$container.on(
            "mousewheel.disablescroll DOMMouseScroll.disablescroll touchmove.disablescroll",
            t._handleWheel
        );

        t.$container.on("scroll.disablescroll", function() {
            t._handleScrollbar.call(t);
        });

        if(t.opts.handleKeys) {
            t.$document.on("keydown.disablescroll", function(event) {
                t._handleKeydown.call(t, event);
            });
        }
    };

    proto.undo = function() {
        var t = this;
        t.$container.off(".disablescroll");
        if(t.opts.handleKeys) {
            t.$document.off(".disablescroll");
        }
    };

    proto._handleWheel = function(event) {
        event.preventDefault();
    };

    proto._handleScrollbar = function() {
        this.$container.scrollLeft(this.lockToScrollPos[0]);
        this.$container.scrollTop(this.lockToScrollPos[1]);
    };

    proto._handleKeydown = function(event) {
        for (var i = 0; i < this.opts.scrollEventKeys.length; i++) {
            if (event.keyCode === this.opts.scrollEventKeys[i]) {
                event.preventDefault();
                return;
            }
        }
    };


    // Plugin wrapper for object
    $.fn.disablescroll = function(method) {

        // If calling for the first time, instantiate the object and save
        // reference. The plugin can therefore only be instantiated once per
        // page. You can pass options object in through the method parameter.
        if( ! instance && (typeof method === "object" || ! method)) {
            instance = new UserScrollDisabler(this, method);
        }

        // Instance already created, and a method is being explicitly called,
        // e.g. .disablescroll('undo');
        else if(instance && instance[method]) {
            instance[method].call(instance);
        }

    };

    // Global access
    window.UserScrollDisabler = UserScrollDisabler;

})(jQuery);

유용합니다. NB 나는 jQuery 플러그인 형식으로 이것에 대한 링크로 편집했다 .
Josh Harrison

스크롤 비활성화 버튼이 실제로 작동하면 도움이 될 수 있습니다
cameronjonesweb

@ user1672694, Chrome에서 작동합니다. 브라우저는 무엇이며 어떤 데모 페이지에서 버그를 발견 했습니까? 콘솔에 JS 오류가 있습니까?
Josh Harrison

Chrome (38, Windows 7)에서 가운데 ​​버튼을 클릭 한 상태에서 드래그하여 스크롤 할 수 있습니다.
Sethi

1
무시하십시오. 구속력 mousewheel이 매력적 이라는 것을 알았습니다
adamj

17

오래된 게시물에 답변을해서 죄송하지만 해결책을 찾고 있었고이 질문을 발견했습니다.

컨테이너에 높이를 100 %로 설정하고 스크롤 막대를 표시하는 등이 문제에 대한 해결 방법이 많이 있습니다. overflow-y: scroll 지정 스타일을 지정 있습니다.

내 경우에는 방금 스크롤 막대 overflow: hidden를 사용하여 본문에 추가 하는 동안 표시되는 div를 만들었습니다 .

function disableScroll() {
    document.getElementById('scrollbar').style.display = 'block';
    document.body.style.overflow = 'hidden';
}

요소 스크롤 막대는 다음 스타일을 가져야합니다.

overflow-y: scroll; top: 0; right: 0; display: none; height: 100%; position: fixed;

이것은 회색 스크롤 막대를 보여줍니다. 향후 방문자에게 도움이되기를 바랍니다.


8

나는이 문제에 대한 해결책을 찾고 있었지만 위의 해결책 중 어느 것에도 만족하지 않았기 때문에 ( 이 대답을 쓰는 현재 ) 해결책을 찾았 습니다.

CSS

.scrollDisabled {   
    position: fixed;
    margin-top: 0;// override by JS to use acc to curr $(window).scrollTop()
    width: 100%;
}

JS

var y_offsetWhenScrollDisabled=0;

function disableScrollOnBody(){
    y_offsetWhenScrollDisabled= $(window).scrollTop();
    $('body').addClass('scrollDisabled').css('margin-top', -y_offsetWhenScrollDisabled);
}
function enableScrollOnBody(){
    $('body').removeClass('scrollDisabled').css('margin-top', 0);
    $(window).scrollTop(y_offsetWhenScrollDisabled);
}

내가 추가 한 경우이 나를 위해 일한 발견 overflow-y: scroll받는 .scrollDisabled스타일. 그렇지 않으면, 스크롤바가 매번 숨겨 질 때 약간의 점프가있었습니다. 물론 내 페이지는 가장 큰 디스플레이에서도 스크롤 막대가 필요할 정도로 길기 때문에 나에게만 효과적입니다.
Andrew Miner

7

galambalazs 게시물 에 따르면 터치 장치에 대한 지원을 추가하여 터치 할 수는 있지만 위 또는 아래로 스크롤 할 수는 없습니다.

function disable_scroll() {
   ...
   document.ontouchmove = function(e){ 
        e.preventDefault(); 
   }
}

function enable_scroll() {
   ...
   document.ontouchmove = function(e){ 
     return true; 
   }
}

3
다른 답변의 의견이 아니라 답변이라고 확신하십니까?
IvanH

6

Chrome 56 및 기타 최신 브라우저에서 작동 passive:false하려면 addEventListener통화에 추가 해야합니다 preventDefault. 그래서 나는 이것을 사용하여 모바일에서 스크롤을 멈 춥니 다.

function preventDefault(e){
    e.preventDefault();
}

function disableScroll(){
    document.body.addEventListener('touchmove', preventDefault, { passive: false });
}
function enableScroll(){
    document.body.removeEventListener('touchmove', preventDefault, { passive: false });
}

5

아니요, 다음과 같은 이유로 이벤트 처리를 사용하지 않습니다.

  • 모든 사건이 신체에 도달한다고 보장되는 것은 아닙니다.

  • 텍스트를 선택하고 아래쪽으로 이동하면 실제로 문서가 스크롤됩니다.

  • 이벤트 분리 단계에서 sth 분리가 잘못되면 운명입니다.

숨겨진 텍스트 영역으로 복사 붙여 넣기 작업을 수행 하여이 문제를 물었고 내부적으로 전화하기 전에 텍스트 영역을 선택해야하기 때문에 복사 할 때마다 페이지가 스크롤됩니다. document.execCommand('copy') 됩니다.

어쨌든 그것이 내가가는 길입니다 setTimeout().

document.body.setAttribute('style','overflow:hidden;');
// do your thing...
setTimeout(function(){document.body.setAttribute('style','overflow:visible;');}, 500);

스크롤바가 일시적으로 사라지면서 모멘텀이 깜박입니다.


4

제거 된 스크롤로 달성하려는 것에 따라 스크롤을 제거 할 요소를 클릭 할 수 있습니다 (클릭시 또는 스크롤을 일시적으로 비활성화하려는 다른 트리거).

나는 "임시 스크롤 없음"솔루션을 찾고 있었고 내 요구에 따라 이것이 해결되었습니다.

수업을하다

.fixed{
    position: fixed;
}

그런 다음 Jquery로

var someTrigger = $('#trigger'); //a trigger button
var contentContainer = $('#content'); //element I want to temporarily remove scroll from

contentContainer.addClass('notfixed'); //make sure that the element has the "notfixed" class

//Something to trigger the fixed positioning. In this case we chose a button.
someTrigger.on('click', function(){

    if(contentContainer.hasClass('notfixed')){
        contentContainer.removeClass('notfixed').addClass('fixed');

    }else if(contentContainer.hasClass('fixed')){
        contentContainer.removeClass('fixed').addClass('notfixed');
    };
});

나는 이것이 모든 브라우저에서 잘 작동하고 휴대용 장치 (예 : iPhone, 태블릿 등)에서도 간단하게 사용할 수있는 간단한 솔루션이라는 것을 알았습니다. 요소가 일시적으로 고정되어 있으므로 스크롤이 없습니다. :)

노트! "contentContainer"요소의 배치에 따라 왼쪽에서 조정해야 할 수도 있습니다. 고정 클래스가 활성화되어있을 때 해당 요소에 CSS 왼쪽 값을 추가하여 쉽게 수행 할 수 있습니다

contentContainer.css({
    'left': $(window).width() - contentContainer.width()/2 //This would result in a value that is the windows entire width minus the element we want to "center" divided by two (since it's only pushed from one side)
});

4

다른 해결책 :

body {
    overflow-y: scroll;
    width: 100%;
    margin: 0 auto;
}

이렇게하면 항상 세로 스크롤 막대가 있지만 대부분의 내용이 뷰포트보다 길기 때문에 괜찮습니다. 내용은 별도의 div를 중심으로하지만 본문에 여백을 다시 설정하지 않으면 내용이 왼쪽에 유지됩니다.

다음은 팝업 / 모달을 표시하는 데 사용하는 두 가지 기능입니다.

var popup_bodyTop = 0;
var popup_bodyLeft = 0;

function popupShow(id)
{
    $('#'+ id).effect('fade');
    $('#popup-overlay').effect('fade');

    // remember current scroll-position
    // because when setting/unsetting position: fixed to body
    // the body would scroll to 0,0
    popup_bodyLeft = $(document).scrollLeft();
    popup_bodyTop  = $(document).scrollTop();

    // invert position
    var x = - popup_bodyLeft;
    var y = - popup_bodyTop;

    $('body').css('position', 'fixed');
    $('body').css('top', y.toString() +'px');
    $('body').css('left', x.toString() +'px');
}

function popupHide(id)
{
    $('#'+ id).effect('fade');
    $('#popup-overlay').effect('fade');
    $('body').css('position', '');
    $('html, body').scrollTop(popup_bodyTop);
    $('html, body').scrollLeft(popup_bodyLeft);
}

결과 : 왼쪽 스크롤 막대로 인해 스크롤 할 수없는 배경 및 컨텐츠 재배치가 없습니다. 현재 FF, Chrome 및 IE 10에서 테스트되었습니다.


이것은 나에게 도움이되었고 position : fixed를 사용한 후 맨 위로 스크롤하는 문제가있었습니다. 고마워!
Annia Martinez

3

이건 어때요? (jQuery를 사용하는 경우)

var $window = $(window);
var $body = $(window.document.body);

window.onscroll = function() {
    var overlay = $body.children(".ui-widget-overlay").first();

    // Check if the overlay is visible and restore the previous scroll state
    if (overlay.is(":visible")) {
        var scrollPos = $body.data("scroll-pos") || { x: 0, y: 0 };
        window.scrollTo(scrollPos.x, scrollPos.y);
    }
    else {
        // Just store the scroll state
        $body.data("scroll-pos", { x: $window.scrollLeft(), y: $window.scrollTop() });
    }
};

약간 어색하지만 IE 7 (클라이언트가 사용)에서 작동합니다. 다른 솔루션은 그렇지 않습니다.
niki b

3

showModalDialog를 사용하고 있습니다보조 페이지를 모달 대화 상자로 표시하기 위해 있습니다.

메인 윈도우 스크롤바를 숨기려면 :

document.body.style.overflow = "hidden";

모달 대화 상자를 닫을 때 기본 창 스크롤 막대가 표시됩니다.

document.body.style.overflow = "scroll";

대화 상자에서 주 창의 요소에 액세스하려면 :

parent.document.getElementById('dialog-close').click();

showModalDialog :( 원본 코드의 29 행 이후) 에 대해 검색하는 사람 만

document.getElementById('dialog-body').contentWindow.dialogArguments = arg;
document.body.style.overflow = "hidden";//****
document.getElementById('dialog-close').addEventListener('click', function(e) {
    e.preventDefault();
    document.body.style.overflow = "scroll";//****
    dialog.close();
});

이것은 jQuery가 존재하지 않고 React가 body 태그의 상태를 관리 할 수있는 React에서 나를 위해 일했습니다.
Jon

3

수락 된 답변에서와 같이 이벤트를 취소하는 것은 내 의견으로는 끔찍한 방법입니다.

대신에 나는 position: fixed; top: -scrollTop(); 아래에서 .

데모 : https://jsfiddle.net/w9w9hthy/5/

내 jQuery 팝업 프로젝트에서 : https://github.com/seahorsepip/jPopup

//Freeze page content scrolling
function freeze() {
    if($("html").css("position") != "fixed") {
        var top = $("html").scrollTop() ? $("html").scrollTop() : $("body").scrollTop();
        if(window.innerWidth > $("html").width()) {
            $("html").css("overflow-y", "scroll");
        }
        $("html").css({"width": "100%", "height": "100%", "position": "fixed", "top": -top});
    }
}

//Unfreeze page content scrolling
function unfreeze() {
    if($("html").css("position") == "fixed") {
        $("html").css("position", "static");
        $("html, body").scrollTop(-parseInt($("html").css("top")));
        $("html").css({"position": "", "width": "", "height": "", "top": "", "overflow-y": ""});
    }
}

이 코드는 너비, 높이, 스크롤 막대 및 페이지 점프 문제를 고려합니다.

위의 코드로 해결 가능한 문제 :

  • 너비, 고정 위치를 설정할 때 html 요소 너비는 100 %보다 작을 수 있습니다
  • 위와 같은 높이
  • 스크롤 막대, 위치 고정 설정시 페이지 내용이 가로로 바뀌기 전에 스크롤 막대가 있어도 페이지 내용에 더 이상 스크롤 막대가 없습니다.
  • pagejump, 위치를 설정할 때 페이지 스크롤이 고정됨 더 이상 세로 페이지 점프가 발생하지 않습니다.

누구나 페이지 고정 / 고정 해제 코드를 개선 한 경우 알려주십시오. 그래서 개선 사항을 프로젝트에 추가 할 수 있습니다.


3
var winX = null, winY = null;
window.addEventListener('scroll', function () {
    if (winX !== null && winY !== null) {
        window.scrollTo(winX, winY);
    }
});
function disableWindowScroll() {
    winX = window.scrollX;
    winY = window.scrollY;
};
function enableWindowScroll() {
    winX = null;
    winY = null;
};

1
이것이 가장 좋은 해결책입니다.
jfunk

@ jfunk는 간단하고 간결하며 작은 코드로 완벽합니다. 감사합니다
Florent Roques

2

나는 같은 문제가 있는데, 아래는 내가 처리하는 방법입니다.

/* file.js */
var body = document.getElementsByTagName('body')[0];
//if window dont scroll
body.classList.add("no-scroll");
//if window scroll
body.classList.remove("no-scroll");

/* file.css */
.no-scroll{
  position: fixed;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
}

이 도움을 바랍니다.


1

샤이엔 포브스의 대답과 fcalderan을 통해 여기에서 찾은 답을 바탕으로 : 스크롤을 숨기지 마십시오. 스크롤바가 사라지는 Hallodom의 문제를 해결하기 위해

CSS :

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

JS :

whatever.onclick = function(){
    $('body').addClass('preventscroll');
}
whatevertoclose.onclick = function(){
    $('body').removeClass('preventscroll');
}

이 코드는 페이지 상단으로 이동하지만 fcalderan의 코드에는 해결 방법이 있다고 생각합니다.


1

나는 이것이 오래된 질문이라는 것을 알고 있지만, 매우 비슷한 것을해야했고, 얼마 후 답을 찾고 다른 접근법을 시도한 후에 매우 쉬운 솔루션을 사용했습니다.

내 문제는 거의 비슷하고 거의 동일합니다. 단지 차이점은 실제로 스크롤 막대를 표시 할 필요가 없다는 것입니다. 단지 너비가 여전히 사용되는지 확인해야하므로 오버레이가 표시되는 동안 페이지 너비가 변경되지 않습니다. .

오버레이를 화면으로 밀기 시작하면 다음 작업을 수행합니다.

$('body').addClass('stop-scrolling').css('margin-right', 8);

오버레이를 화면 밖으로 밀면 다음과 같습니다.

$('body').removeClass('stop-scrolling').css('margin-right', 0);

중요 : 오버레이가 absolute, right: 0pxwhen 위치에 있기 때문에 완벽하게 작동합니다 visible.


1

가장 간단한 방법은 다음과 같습니다.

$("body").css("overflow", "hidden"); // Remove the scroll bar temporarily

실행 취소하려면 :

$("body").css("overflow", "auto");

구현하기 쉽지만 유일한 단점은 다음과 같습니다.

  • 페이지가 가운데로 정렬되면 (가로) 페이지가 약간 왼쪽으로 이동합니다.

스크롤 막대가 제거되고 뷰포트가 약간 넓어 졌기 때문입니다.


1
스크롤 위치를 재설정합니다
Angel David Calderaro Pacciott

@AngelDavidCalderaroPacciott 아니요, 스크롤 위치는 동일한 높이 / 거리로 유지됩니다.
Daan

@Daan Chrome에서 스크롤 위치를 재설정합니다.
Tom

@Tom 방금 확인했는데 일부 경우에만 수행됩니다 (신체 높이가 자녀와 관련이없는 경우). 변경 시도하십시오 bodyhtml대신.
Daan

나는 당신이 아이폰 원인에 대한 해결책을 확인하지 않았다 내기 왜 overflow:hidden거기에서 작동하지 않습니다
Shuvo

1

다음은 스크롤을 중지하는 솔루션입니다 (jQuery 없음). 사이드 메뉴가 나타날 때 스크롤을 비활성화하는 데 사용합니다.

<button onClick="noscroll()" style="position:fixed; padding: 8px 16px;">Disable/Enable scroll</button>
<script>
var noscroll_var;
function noscroll(){
  if(noscroll_var){
    document.getElementsByTagName("html")[0].style.overflowY = "";
    document.body.style.paddingRight = "0";
    noscroll_var = false
  }else{
    document.getElementsByTagName("html")[0].setAttribute('style', 'overflow-y: hidden !important');
    document.body.style.paddingRight = "17px";
    noscroll_var = true
  }
}/*noscroll()*/
</script>

<!-- Just to fill the page -->
<script>
  for(var i=0; i <= 80; i++){
    document.write(i + "<hr>")
  }
</script>

스크롤 막대가 사라지는 것을 보완하기 위해 17px의 padding-right를 넣었습니다. 그러나 이것은 대부분 모바일 브라우저에서도 문제가됩니다. 이것 에 따라 막대 너비를 가져 와서 해결 .

이 펜에서 모두 함께.



1

이것이 내가 지금까지 얻은 가장 간단한 솔루션입니다. 그리고 다른 모든 것을 시도해 보았고 이것이 가장 쉬운 방법이라고 믿습니다. 그것은 Windows 장치 에서 훌륭하게 작동 합니다 . 이는 페이지를 오른쪽에서 밀어서 시스템 스크롤 막대 및 브라우저에 스크롤 막대를위한 공간이 필요없는 IOS 장치 를위한 공간을 확보합니다. 따라서 이것을 사용하면 오른쪽에 패딩을 추가 할 필요가 없으므로 CSS로 본문 또는 HTML의 오버플로숨길 때 페이지가 깜박이지 않습니다 .

당신이 그것에 대해 생각하면 솔루션은 매우 간단합니다. 아이디어는 팝업이 열리는 순간에 window.scrollTop () 에 정확한 위치를 제공하는 것입니다. 또한 창 크기가 조정되면 스크롤 위치가 변경되면 해당 위치를 변경하십시오.

그래서 우리는 간다 ...

먼저 팝업이 열려 있음을 알리고 stopWindowScroll 이라는 변수를 만들 수 있습니다 . 이렇게하지 않으면 페이지에 정의되지 않은 변수 오류가 발생하고 활성화되지 않은 상태로 0으로 설정됩니다.

$(document).ready(function(){
    stopWindowScroll = 0;
});

이제 팝업 열기 기능 스위치를 코드에서 플러그인 또는 사용자 정의로 사용하는 팝업을 트리거하는 모든 기능으로 만들 수 있습니다. 이 경우 클릭 기능에 대한 간단한 문서가있는 간단한 사용자 정의 팝업이됩니다.

$(document).on('click','.open-popup', function(){
    // Saving the scroll position once opening the popup.
    stopWindowScrollPosition = $(window).scrollTop();
    // Setting the stopWindowScroll to 1 to know the popup is open.
    stopWindowScroll = 1;
    // Displaying your popup.
    $('.your-popup').fadeIn(300);
});

다음으로 우리가하는 일은 close popup 함수를 만드는 것입니다. 다시 반복하는 함수는 이미 작성했거나 플러그인에서 사용하고있는 함수일 수 있습니다. 중요한 것은 stopWindowScroll 변수를 1 또는 0으로 설정하여 변수가 열리거나 닫히는 시점을 알기 위해서는이 두 함수가 필요하다는 것입니다 .

$(document).on('click','.open-popup', function(){
    // Setting the stopWindowScroll to 0 to know the popup is closed.
    stopWindowScroll = 0;
    // Hiding your popup
    $('.your-popup').fadeOut(300);
});

그런 다음 위에서 언급 한 stopWindowScroll 이 1로 설정 되면 스크롤을 방지 할 수 있도록 window.scroll 함수를 만듭니다 .

$(window).scroll(function(){
    if(stopWindowScroll == 1) {
         // Giving the window scrollTop() function the position on which
         // the popup was opened, this way it will stay in its place.
         $(window).scrollTop(stopWindowScrollPosition);
    }
});

그게 다야. 페이지 스타일을 제외하고는 CSS가 필요하지 않습니다. 이것은 나에게 매력처럼 작용했으며 그것이 당신과 다른 사람들을 돕기를 바랍니다.

JSFiddle에 대한 실제 예제는 다음과 같습니다.

JS 피들 예제

이것이 도움이되었는지 알려주십시오. 문안 인사.


1

스크롤 길이를 전역 변수에 저장하고 필요할 때 복원하십시오!

var sctollTop_length = 0;

function scroll_pause(){
  sctollTop_length = $(window).scrollTop();
  $("body").css("overflow", "hidden");
}

function scroll_resume(){
  $("body").css("overflow", "auto");
  $(window).scrollTop(sctollTop_length);
}

1

이 코드는 Chrome 56 이상에서 작동합니다 (원래 답변은 더 이상 Chrome에서 작동하지 않음).

사용하다 DomUtils.enableScroll()스크롤을 활성화하는 데 합니다.

DomUtils.disableScroll()스크롤을 비활성화하는 데 사용 합니다.

class DomUtils {
  // left: 37, up: 38, right: 39, down: 40,
  // spacebar: 32, pageup: 33, pagedown: 34, end: 35, home: 36
  static keys = { 37: 1, 38: 1, 39: 1, 40: 1 };

  static preventDefault(e) {
    e = e || window.event;
    if (e.preventDefault) e.preventDefault();
    e.returnValue = false;
  }

  static preventDefaultForScrollKeys(e) {
    if (DomUtils.keys[e.keyCode]) {
      DomUtils.preventDefault(e);
      return false;
    }
  }

  static disableScroll() {
    document.addEventListener('wheel', DomUtils.preventDefault, {
      passive: false,
    }); // Disable scrolling in Chrome
    document.addEventListener('keydown', DomUtils.preventDefaultForScrollKeys, {
      passive: false,
    });
  }

  static enableScroll() {
    document.removeEventListener('wheel', DomUtils.preventDefault, {
      passive: false,
    }); // Enable scrolling in Chrome
    document.removeEventListener(
      'keydown',
      DomUtils.preventDefaultForScrollKeys,
      {
        passive: false,
      }
    ); // Enable scrolling in Chrome
  }
}

1

점프를 막기 위해 이것이 내가 사용한 것입니다.

export function toggleBodyScroll(disable) {
  if (!window.tempScrollTop) {
    window.tempScrollTop = window.pageYOffset; 
    // save the current position in a global variable so I can access again later

  }
  if (disable) {
    document.body.classList.add('disable-scroll');
    document.body.style.top = `-${window.tempScrollTop}px`;
  } else {
    document.body.classList.remove('disable-scroll');
    document.body.style.top = `0px`;
    window.scrollTo({top: window.tempScrollTop});
    window.tempScrollTop = 0;
  }
}

내 CSS에서

.disable-scroll {
  height: 100%;
  overflow: hidden;
  width: 100%;
  position: fixed;
}

0

다른 사이트 에서이 답변을 찾았습니다 .

스크롤 비활성화 :

$( ".popup").live({
    popupbeforeposition: function(event, ui) {
    $("body").on("touchmove", false);
}
});

팝업 해제 스크롤 후 :

$( ".popup" ).live({
    popupafterclose: function(event, ui) {
    $("body").unbind("touchmove");
}
});

터치 스크롤 만 중지하는 것처럼 보이지만 마우스 스크롤, 화살표 키, 페이지 위로 및 아래로 키 등은 계속 작동합니다. -1
markasoftware

이 '이벤트'는 터치 스크롤을위한 것이며 필요한 이벤트 만 대체하면됩니다.
pennstump

1
또한 이것은 매우 다른 특정 상황에서 사용되는 것으로 보입니다. 팝업 전 위치? 그게 뭐야? 이것은 일시적으로 스크롤을 비활성화하는 것과 어떤 관련이 있습니까? 최소한이 상황과 관련이 있어야합니다. 웹 사이트에서 직접 복사 한 것 같습니다.
markasoftware

0

galambalazs의 솔루션은 훌륭합니다! Chrome과 Firefox 모두에서 완벽하게 작동했습니다. 또한 브라우저 창에서 기본 이벤트가 발생하지 않도록 확장 할 수도 있습니다. 캔버스에서 앱을 만들고 있다고 가정 해 봅시다. 당신은 이것을 할 수 있습니다 :

var events = {
  preventDefault: function(e) {
    e = e || window.event;
    if (e.preventDefault) e.preventDefault();
    e.returnValue = false;  
  },

  //spacebar: 32, pageup: 33, pagedown: 34, end: 35, home: 36,
  //left: 37, up: 38, right: 39, down: 40
  keys: [32, 33, 34, 35, 36, 37, 38, 39, 40],
  keydown: function(e) {
    for (var i = events.keys.length; i--;) {
      if (e.keyCode === events.keys[i]) {
        events.preventDefault(e);
        return;
      }
    }
  },

  wheel: function(e) {
    events.preventDefault(e);
  },

  disable: function() {
    if (window.addEventListener) {
      window.addEventListener('DOMMouseScroll', events.wheel, false);
    }
    window.onmousewheel = document.onmousewheel = events.wheel;
    document.onkeydown = helpers.events.keydown;
  },

  enable: function() {
    if (window.removeEventListener) {
      window.removeEventListener('DOMMouseScroll', events.wheel, false);
    }
    window.onmousewheel = document.onmousewheel = document.onkeydown = null;  
  }
}

그런 다음 앱에서 마우스, 키보드, 터치 이벤트 등과 같은 자체 이벤트를 처리한다고 가정 해 봅시다. 마우스가 캔버스 안에 들어가면 기본 이벤트를 비활성화하고 마우스를 다시 활성화 할 수 있습니다 외출:

function setMouseEvents(canvas) {
  var useCapture = false;

  //Mouse enter event
  canvas.addEventListener('mouseenter', function(event) {
    events.disable();
  }, useCapture);

  //Mouse leave event
  canvas.addEventListener('mouseleave', function(event) {
    events.enable();
  }, useCapture);
}

이 핵으로 마우스 오른쪽 버튼 클릭 메뉴를 비활성화 할 수도 있습니다.

function disableRightClickMenu(canvas) {
  var my_gradient = canvas.context.createLinearGradient(0, 0, 0, 225);
  my_gradient.addColorStop(0, "white");
  my_gradient.addColorStop(1, "white");
  canvas.context.fillStyle = my_gradient;
  canvas.context.fillRect(0, 0, canvas.width, canvas.height);
  canvas.oncontextmenu = function() { return false; };
}

0

jquery의 animate 명령을 사용하여 div에 애니메이션을 적용하려고 할 때 모바일 화면에서는 유사한 애니메이션 문제가 있었지만 랩톱에서는 그렇지 않았습니다. 그래서 나는 창의 스크롤 위치를 너무 자주 복원하여 문서를 맨 눈으로 볼 수있는 타이머를 사용하기로 결정했습니다. 이 솔루션은 Samsung Galaxy-2 또는 iphone-5와 같은 소형 화면 모바일 장치에서 완벽하게 작동했습니다.

이 접근법의 주요 논리 : jquery animate 명령 전에 창의 스크롤 위치를 원래 스크롤 위치로 설정하는 타이머를 시작한 다음 애니메이션이 완료되면이 타이머를 지워야합니다 ( original scroll position애니메이션이 시작되기 직전의 위치).

나는 깜짝 선물로 발견 문서가 실제로 타이머 간격이 있다면 애니메이션 기간 동안 정적 등장 것을 1 millisecond내가 목표로 무슨이다.

//get window scroll position prior to animation
//so we can keep this position during animation
var xPosition = window.scrollX || window.pageXOffset || document.body.scrollLeft;
var yPosition = window.scrollY || window.pageYOffset || document.body.scrollTop;

//NOTE:restoreTimer needs to be global variable
//start the restore timer
restoreTimer = setInterval(function() {
    window.scrollTo(xPosition, yPosition);
}, 1);

//animate the element emt
emt.animate({
    left: "toggle",
    top: "toggle",
    width: "toggle",
    height: "toggle"
}, 500, function() {
    //when animation completes, we stop the timer
    clearInterval(restoreTimer);
});

다른 해결책 : 스크롤링을 활성화 / 비활성화하기위한이 게시물 아래의 Mohammad Anini의 답변을 바탕으로 아래 수정 된 코드 버전이 작동한다는 것을 알았습니다.

//get current scroll position
var xPosition = window.scrollX || window.pageXOffset || document.body.scrollLeft;
var yPosition = window.scrollY || window.pageYOffset || document.body.scrollTop;

//disable scrolling
window.onscroll = function() {
    window.scrollTo(xPosition, yPosition);
};

//animate and enable scrolling when animation is completed
emt.animate({
    left: "toggle",
    top: "toggle",
    width: "toggle",
    height: "toggle"
}, 500, function() {
    //enable scrolling when animation is done
    window.onscroll = function() {};
});

0

나를 위해 일한 간단한 솔루션 (일시적으로 창 스크롤 사용 안 함).

이 바이올린을 기반으로 : http://jsfiddle.net/dh834zgw/1/

다음 스 니펫 (jquery 사용)은 창 스크롤을 비활성화합니다.

 var curScrollTop = $(window).scrollTop();
 $('html').toggleClass('noscroll').css('top', '-' + curScrollTop + 'px');

그리고 당신의 CSS에서 :

html.noscroll{
    position: fixed;
    width: 100%;
    top:0;
    left: 0;
    height: 100%;
    overflow-y: scroll !important;
    z-index: 10;
 }

이제 모달을 제거 할 때 html 태그에서 noscroll 클래스를 제거하는 것을 잊지 마십시오.

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