一時的にスクロールを無効にする方法は?


434

scrollTo jQueryプラグインを使用していますが、JavaScriptを使用してウィンドウ要素のスクロールを一時的に無効にできるかどうかを知りたいですか?スクロールを無効にしたいのは、scrollToがアニメーションしているときにスクロールすると、醜くなります;)

もちろん、a $("body").css("overflow", "hidden");を実行し、アニメーションが停止したらautoに戻すこともできますが、スクロールバーがまだ表示されているが非アクティブである方が良いでしょう。


12
それがまだ表示されている場合、ユーザーはそれが機能している必要があると考えるように訓練されています。線量が移動しない、または線量が応答しない場合、ページがどのように機能するかについてのユーザーのメンタルモデルが崩れ、混乱が生じます。たとえばアニメーションを停止するなど、アニメーションしながらスクロールを処理するためのより良い方法を見つけます。
Marcus Whybrow、2011年

回答:


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分は他の人の時間を節約するのに役立ちます:)
Dirk van Bergen

4
無効なキー配列に32(スペース)を追加できます(コードコメントに表示)。
gblazex 2013年

14
これはいつものようにスクロールできます。中ボタンを押してマウスを動かします...したがって、このトリックは私のようなユーザーには影響しません;)
Denis V

11
スクロールバーは無効になりません。
verism 2014年

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 2012年

3
クール、タッチデバイスのモーダルで内部スクロールが機能することを確認する必要があります。モーダルのすぐ下にオーバーレイを実行して、本体ではなくオーバーレイのデフォルトのタッチムーブを防ぐことができます。
Hallodom 2012年

63
このソリューションは機能しますが、ページの先頭にスクロールして戻る(潜在的に)望ましくない影響があります。
マット

3
私のセレクタがそうでない限り、これは私にとっては$('body,html')
うまくいき

22
このソリューションは機能しますが、このクラスをボディに適用すると(たとえば)、スクロールバーが消えて「バンプ」効果(ウィンドウOSの下)が作成されます
Georgio

57

これを行うための本当に基本的な方法は次のとおりです。

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

それはIE6でちょっとびくびくしています。


14
実際には無効化ではなく、スクロールを試みたときにデフォルトにスナップするようなものです。
Marcus Whybrow、2011年

11
@Marcusキャンセルできないイベントを取得するのと同じくらい良いです。
sdleihssirhc

3
実際にそれを無効にするわけではありませんが、それはそれをシミュレートし、それで十分です。
Chris Bier

11
私見-ここでのベストアンサー。さらに、それをにロックする必要はありません(0, 0)。現在のスクロール位置を使用してください。
YemSalat

4
しかし、それをどのようにして再び有効にするのでしょうか?
サイバネティック

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。
TimoKähkönen14年

まだ最新のChromeで少しびくびく
Jason Allshorn 2018年

サファリ、クロームで問題なく動作するが、IEではちらつく
Bhuvan Arora 2018

このソリューションが一部のブラウザで機能しない場合は、それがブラウザの問題です
Oto Shavadze

別の回答で述べたように、scroll-behavior: smoothこれは間違いです。また、それはブラウザのせいだと大藤に反対する。あなたは基本的に何かが実際にはそれが非同期であるときに即座に起こると仮定しています
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);

便利です。注意:これへリンクをjQueryプラグイン形式で編集しました。
Josh Harrison

無効化スクロールボタンが実際に機能した場合に役立つことがあります
cameronjonesweb

@ user1672694、それはここChromeで動作します。あなたのブラウザは何で、どのデモページでバグが見つかりましたか?コンソールにJSエラーがありますか?
ジョシュ・ハリソン

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 2013

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がうまくいかない場合、あなたは運命にあります。

非表示のtextareaを使用してコピーと貼り付けのアクションを実行することでこれをかみました。コピーを作成するたびにページがスクロールします。内部的には呼び出す前にtextareaを選択する必要があるためです。 document.execCommand('copy')。です。

とにかくそれは私が行く方法です、注意してsetTimeout()ください:

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

スクロールバーが一時的に消えるので、勢いが点滅しますが、それは許容できることです。


4

削除されたスクロールで何を達成したいかに応じて、スクロールを削除したい要素を修正することができます(クリック、または一時的にスクロールを非アクティブ化したい他のトリガー)

「temp no scroll」ソリューションを探していて、私のニーズのためにこれで解決しました

クラスを作る

.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 left値を追加することで簡単に実行できます

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で中央揃えされますが、本文に再度マージンを設定しないと、コンテンツは左側に留まります。

これらは、ポップアップ/モーダルを表示するために使用する2つの関数です。

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 14

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、位置を設定すると、ページscrollTopが効果的でなくなり、垂直ページジャンプが発生する

上記のページのフリーズ/フリーズ解除コードに改善があった場合は、私に知らせて、プロジェクトにそれらの改善を追加できるようにしてください。


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は同意し、シンプルで簡潔、小さなコード、完璧です。ありがとう
フローレントロック

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

重要:私のオーバーレイが配置されているので、これは完璧に動作しabsoluteright: 0pxときvisible


1

最も簡単な方法は次のとおりです。

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

元に戻すには:

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

実装は簡単ですが、唯一の欠点は次のとおりです。

  • ページが中央揃え(水平)の場合、ページは少し左にジャンプします。

これは、スクロールバーが削除され、ビューポートが少し広くなっているためです。


1
スクロール位置がリセットされます
エンジェルデビッドカルデラロパッチオット

@AngelDavidCalderaroPacciottいいえ、スクロール位置は同じ高さ/距離のままです。
Daan、

@DaanはChromeのスクロール位置をリセットします
Tom

@Tom私はちょうどそれをチェックしました、それはいくつかの場合にのみそれを行います(体の高さがその子供に関連していないとき)。代わりに変更bodyしてみてくださいhtml
Daan

私はあなたのiPhoneの原因でソリューションをチェックしませんでした賭ける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のパディングライトを配置しました。しかし、これはまた、主にモバイルブラウザで問題になります。これに従ってバーの幅を取得することで解決しました。

このペンですべて一緒に。



1

これは私がこれまでに得た最も簡単な解決策です。そして、私が他のすべてを試した私を信じて、これが最も簡単なものです。これは、ページを右から押してシステムスクロールバーのスペースを確保するWindowsデバイスと、ブラウザーのスクロールバーにスペースを必要としないIOSデバイスでうまく機能します。したがって、これを使用することで右側にパディングを追加する必要がなくなり、cssでbodyまたは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);
});

したがって、次に行うのは、閉じるポップアップ関数を作成することです。繰り返しますが、これは、既に作成した、またはプラグインで使用している任意の関数にすることができます。重要なことは、これらの2つの関数が 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);
});

次にwindow.scroll関数を作成して、一度スクロールしないようにします。 上記 stopWindowScrollが1に設定された(アクティブとして)とします。

$(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 Fiddleの例

これで問題が解決したかどうかをお知らせください。よろしく。


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 2013

これらの「イベント」はタッチスクロール用であり、必要なイベントを置き換えるだけです。
pennstump 2013

1
また、これは他の非常に特殊な状況で使用されるようです。popupbeforeposition?それは何のためにあるのですか?これはスクロールを一時的に無効にすることと何が関係していますか?少なくともこの状況に関連するようにします。これをウェブサイトから直接コピーしたようです。
markasoftware 2013

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のアニメーションコマンドを使用して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.