Comment désactiver temporairement le défilement?

j'utilise le plugin scrollTo jQuery et je voudrais savoir s'il est possible de désactiver temporairement le défilement sur l'élément window par Javascript? La raison pour laquelle j'aimerais désactiver le défilement est que lorsque vous faites défiler scrollTo pendant que scrollTo est animé, il devient vraiment laid ;)

bien sûr, je pourrais faire un $("body").css("overflow", "hidden"); et le remettre en Automatique quand l'animation s'arrête, mais ce serait mieux si la barre de défilement était encore visible mais inactive.

366
demandé sur Olivier Lalonde 2011-01-22 22:23:44

30 réponses

l'événement scroll ne peut être annulé. Mais vous pouvez le faire par annuler ces événements d'interaction:

Souris & Touche de défilement et Boutons associé avec le défilement.

[ "1519170920 de Travail" démo ]

// 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 = e || window.event;
  if (e.preventDefault)
      e.preventDefault();
  e.returnValue = false;  
}

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

function disableScroll() {
  if (window.addEventListener) // older FF
      window.addEventListener('DOMMouseScroll', preventDefault, false);
  window.onwheel = preventDefault; // modern standard
  window.onmousewheel = document.onmousewheel = preventDefault; // older browsers, IE
  window.ontouchmove  = preventDefault; // mobile
  document.onkeydown  = preventDefaultForScrollKeys;
}

function enableScroll() {
    if (window.removeEventListener)
        window.removeEventListener('DOMMouseScroll', preventDefault, false);
    window.onmousewheel = document.onmousewheel = null; 
    window.onwheel = null; 
    window.ontouchmove = null;  
    document.onkeydown = null;  
}
634
répondu galambalazs 2015-07-05 11:51:43

de le Faire simplement par l'ajout d'une classe au corps:

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

ajouter la classe puis supprimer lorsque vous voulez réactiver le défilement, testé dans IE, FF, Safari et Chrome.

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

pour appareils mobiles , vous aurez besoin de gérer le touchmove événement:

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

et déboutonner pour réactiver le défilement. Testé sur iOS6 et Android 2.3.3

$('body').unbind('touchmove')
381
répondu hallodom 2012-11-19 21:24:07

Voici une façon vraiment basique de le faire:

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

c'est un peu nerveux dans IE6.

46
répondu sdleihssirhc 2011-01-22 19:29:56

cette solution maintiendra la position de défilement actuelle pendant que le défilement est désactivé, contrairement à certains qui sautent l'utilisateur de nouveau au sommet.

il est basé sur réponse de galambalazs , mais avec support pour les dispositifs tactiles, et refactorisé comme un seul objet avec jQuery plugin wrapper.

démo ici.

sur github ici.

/**
 * $.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);
23
répondu Josh Harrison 2017-05-23 12:02:57

la solution suivante est JavaScript basique mais pur (no jQuery):

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

function enableScrolling(){
    window.onscroll=function(){};
}
22
répondu Mohammad Anini 2014-10-03 21:21:29

je suis désolé de répondre à un vieux message, mais je cherchais une solution et suis tombé sur cette question.

il existe de nombreuses solutions de rechange pour ce numéro d'afficher encore le scrollbar, comme donner au conteneur une hauteur de 100% et un style overflow-y: scroll .

dans mon cas je viens de créer un div avec un scrollbar que j'affiche en ajoutant overflow: hidden au corps:

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

l'élément scrollbar doit avoir ceci styles:

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

cela montre un scrollbar gris, espérons qu'il aide les futurs visiteurs.

14
répondu lisovaccaro 2017-02-24 01:23:28

selon le galambalazs post je voudrais ajouter le support pour les dispositifs tactiles, nous permettant de toucher mais pas de faire défiler vers le haut ou vers le bas:

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

function enable_scroll() {
   ...
   document.ontouchmove = function(e){ 
     return true; 
   }
}
7
répondu jvalen 2013-08-23 13:33:53

je cherchais une solution à ce problème mais n'étais pas satisfait de l'une des solutions ci-dessus ( au moment d'écrire cette réponse ), donc j'ai trouvé cette solution..

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);
}
7
répondu Rajat Gupta 2014-11-09 08:46:47

une autre solution:

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

de cette façon, vous avez toujours un scrollbar vertical, mais comme la plupart de mon contenu est plus long que le viewport, c'est ok pour moi. Le contenu est centré avec un div séparé, mais sans fixer la marge à nouveau dans le corps mon contenu resterait à gauche.

ce sont les deux fonctions que j'utilise pour afficher mon popup/modal:

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

résultat: fond non contrôlable et pas de repositionnement de le contenu à cause du scrollbar gauche. Testé avec FF, Chrome et IE 10.

4
répondu Marco 2017-02-23 23:56:22

et ça? (Si vous utilisez 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() });
    }
};
3
répondu Dan 2013-04-23 07:34:30

Selon ce que vous voulez atteindre avec l'retiré de défilement, vous pouvez simplement fixer l'élément que vous souhaitez supprimer, faites défiler (au clic, ou tout autre déclencheur que vous souhaitez désactiver temporairement scroll)

je cherchais une solution "temp no scroll" et pour mes besoins, cela l'a résolu

faire une classe

.fixed{
    position: fixed;
}

puis avec 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');
    };
});

j'ai trouvé que ce était une solution assez simple qui fonctionne bien sur tous les navigateurs, et permet également une utilisation simple sur les appareils portables (i.e. iPhones, tablettes, etc). Comme l'élément est fixé Temporairement, il n'y a pas de scroll :)

NOTE! En fonction de l'emplacement de votre élément "contentContainer", vous devrez peut-être l'ajuster à partir de la gauche. Ce qui peut facilement être fait en ajoutant une valeur CSS gauche à cet élément lorsque la classe fixe est active

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)
});
3
répondu axelra82 2013-08-15 11:42:07

j'utilise showModalDialog 151980920" , pour afficher la page secondaire comme Dialogue modal.

pour cacher les barres de défilement de la fenêtre principale:

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

et lors de la fermeture du Dialogue modal, montrant les barres de défilement de la fenêtre principale:

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

pour accéder aux éléments dans la fenêtre principale de dialogue:

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

juste pour tous ceux qui cherchent à propos de showModalDialog : (après ligne 29 du code original)

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();
});
3
répondu Zolfaghari 2016-03-05 14:10:29

annuler l'événement comme dans la réponse acceptée est une méthode horrible à mon avis: /

à la place j'ai utilisé position: fixed; top: -scrollTop(); ci-dessous.

Démo: https://jsfiddle.net/w9w9hthy/5/

de mon projet jQuery popup: 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": ""});
    }
}

ce code prend, largeur, hauteur, scrollbar et pagejump questions en considération.

problèmes possibles résolus avec le code ci-dessus:

  • largeur, lorsque la position est fixe la largeur de l'élément html peut être plus petite que 100%
  • hauteur, même que ci-dessus
  • scrollbar, lors du réglage de la position fixé le contenu de la page n'a plus de scrollbar même quand il avait une barre de défilement avant d'aboutir à un saut de page horizontal
  • pagejump, lors du réglage position fixe la page scrollTop n'est plus efficace résultant en un saut de page vertical

si quelqu'un a des améliorations à la page ci-dessus, faites-moi savoir pour que je puisse ajouter ces améliorations à mon projet.

2
répondu seahorsepip 2017-02-24 00:20:21

à partir de Chrome 56 et d'autres navigateurs modernes, vous devez ajouter passive:false à la addEventListener appel à faire preventDefault travail. Donc je l'utilise pour arrêter de défiler sur mobile:

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

function disableScroll(){
    document.body.addEventListener('touchmove', preventDefault, { passive: false });
}
function enableScroll(){
    document.body.removeEventListener('touchmove', preventDefault, { passive: false });
}
2
répondu Hokascha 2017-09-26 10:09:40

basé sur la réponse de Cheyenne Forbes, et celui que j'ai trouvé ici via fcalderan: juste désactiver scroll pas le cacher? et pour régler la question de Hallodom de la disparition du scrollbar

CSS:

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

JS:

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

ce code vous amène en haut de la page, mais je pense que le code de fcalderan a une solution.

1
répondu Quibble 2017-08-13 19:27:14

je sais que c'est une vieille question, mais j'ai dû faire quelque chose de très similaire, et après un certain temps à la recherche d'une réponse et en essayant différentes approches, j'ai fini par utiliser une solution très facile.

mon problème était très similaire, presque identique, la seule différence est que je n'avais pas à afficher la barre de défilement - je devais juste m'assurer que sa largeur serait encore utilisée, de sorte que la largeur de la page ne changerait pas pendant que ma superposition était affichée.

Quand je commence à glisser ma superposition dans l'écran, je fais:

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

et après avoir fait glisser ma superposition de l'écran je fais:

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

IMPORTANT: cela fonctionne parfaitement parce que ma superposition est positionnée absolute , right: 0px quand visible .

1
répondu user2430829 2017-09-25 12:08:17

j'ai le même problème, voici la façon dont je le manipuler.

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

espérons que cette aide.

1
répondu sou yang 2017-12-18 03:55:52

la méthode la plus simple est:

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

Pour le défaire:

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

facile à mettre en œuvre, mais le seul inconvénient est:

  • la page sautera un peu à gauche si elle est alignée au centre (horizontalement).

ceci est dû au fait que la barre de défilement a été supprimée, et que le viewport est devenu un peu plus large.

1
répondu Daan 2018-02-20 22:23:51

voici ma solution pour arrêter le rouleau (no jQuery). - Je l'utiliser pour désactiver le défilement lorsque le menu s'affiche.

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

j'ai mis 17px de rembourrage-droit pour compenser la disparition de la barre de rouleau. Mais c'est aussi problématique, surtout pour les navigateurs mobiles. Résolu en obtenant la largeur de la barre selon ce .

tous ensemble dans ce stylo.

1
répondu Josep81 2018-03-07 01:59:13

j'ai trouvé cette réponse sur un autre site :

Désactiver le défilement:

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

après le rouleau popup de fermeture:

$( ".popup" ).live({
    popupafterclose: function(event, ui) {
    $("body").unbind("touchmove");
}
});
0
répondu pennstump 2013-04-25 23:38:21

la solution de galambalazs est géniale! Cela a fonctionné parfaitement pour moi dans les deux Chrome et Firefox. Et il peut également être étendu pour prévenir tout événement par défaut à partir de la fenêtre du navigateur. Disons que vous faites une application sur la toile. Vous pourriez faire ceci:

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

Et ensuite sur votre application disons que vous allez traiter vos propres événements, comme la souris, le clavier, la touche et les évènements... Vous pouvez désactiver les événements par défaut lorsque la souris va à l'intérieur de la toile et re-enable quand la souris sort:

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

vous pourriez même désactiver le menu de clic droit avec ce hack:

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
répondu Rafael 2014-12-23 14:43:53

j'ai eu un problème d'animation similaire sur les écrans mobiles mais pas sur les ordinateurs portables, en essayant d'animer une div en utilisant la commande animate de jquery. J'ai donc décidé d'utiliser une minuterie qui restaurait la position de défilement de la fenêtre si souvent qu'à l'oeil nu le document paraîtrait statique. Cette solution fonctionnait parfaitement sur un petit écran mobile comme Samsung Galaxy-2 ou iphone-5.

Logique principale de cette approche : la minuterie la position de défilement à la position de défilement originale doit être commencée avant la commande jQuery animate, et ensuite lorsque l'animation est terminée, nous devons effacer cette minuterie ( original scroll position est la position juste avant le début de l'animation).

j'ai trouvé à mon agréable surprise que le document apparaissait en fait statique pendant la durée de l'animation si l'intervalle de minuterie était 1 millisecond , ce qui est ce que je visais.

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

une autre SOLUTION qui a fonctionné : sur la base de la réponse de Mohammad Anini sous ce post pour activer/désactiver le défilement, j'ai également constaté qu'une version modifiée du code comme ci-dessous travaillé.

//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
répondu Sunil 2015-10-03 15:59:19

une solution simple qui a fonctionné pour moi (désactivant temporairement le défilement de la fenêtre).

basé sur ce violon: http://jsfiddle.net/dh834zgw/1 /

le fragment suivant (en utilisant jquery) désactivera le rouleau de la fenêtre:

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

et dans votre css:

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

Maintenant, lorsque vous supprimez le modal, n'oubliez pas de supprimer la classe noscroll sur la balise html:

$('html').toggleClass('noscroll');
0
répondu ling 2016-03-01 06:46:47

quelque Chose que je viens de mettre ensemble:

jsfiddle

document.onwheel = function(e) {
  // get the target element
  target = e.target;
  // the target element might be the children of the scrollable element
  // e.g., "li"s inside an "ul", "p"s inside a "div" etc.
  // we need to get the parent element and check if it is scrollable
  // if the parent isn't scrollable, we move up to the next parent
  while (target.scrollHeight <= target.clientHeight) {
    // while looping parents, we'll eventually reach document.body
    // since body doesn't have a parent, we need to exit the while loop
    if (target == document.body) {
      break;
    }
    target = target.parentElement;
  }
  // we want this behaviour on elements other than the body
  if (target != document.body) {
    // if the scrollbar is at the top and yet if it still tries to scroll up
    // we prevent the scrolling
    if (target.scrollTop <= 0 && e.deltaY < 0) {
      e.preventDefault();
    }
    // similarly, if the scrollbar is at the bottom and it still tries to scroll down
    // we prevent it
    else if (target.clientHeight + target.scrollTop >= target.scrollHeight && e.deltaY > 0) {
      e.preventDefault();
    }
  }
};
body {
  background: gainsboro;
}

#box {
  width: 300px;
  height: 600px;
  padding: 5px;
  border: 1px solid silver;
  margin: 50px auto;
  background: white;
  overflow: auto;
}
<div id="box">
  <p>
    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
    in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
  </p>
  <p>
    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
    in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
  </p>
  <p>
    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
    in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
  </p>
  <p>
    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
    in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
  </p>
</div>
0
répondu akinuri 2017-02-20 18:22:48

vous pouvez bloquer la barre d'espacement et cacher la barre de défilement du navigateur:

$(document).keydown(function(event) {
    if (event.keyCode == 32) {
        return false;

    }
});

document.documentElement.style.overflow = 'hidden';
document.body.scroll = 'no';
0
répondu santyas 2017-02-24 00:21:07

mon point de vue sur cette question inclut également une préoccupation avec la largeur du corps, car la page semble danser un peu quand nous cachons la barre de défilement avec overflow = "hidden" . Le code suivant fonctionne parfaitement pour moi, et est basé sur une approche angulaire.

element.bind('mouseenter', function() {
    var w = document.body.offsetWidth;
    document.body.style.overflow = 'hidden';
    document.body.style.width = w + 'px';
});

element.bind('mouseleave', function() {
    document.body.style.overflow = 'initial';
    document.body.style.width = 'auto';
});
0
répondu Fabio Nolasco 2017-02-24 00:23:14

j'ai un problème similaire sur les appareils tactiles. L'ajout de" touch-action: none " à l'élément a résolu le problème.

pour plus d'information. Regardez ça: -

https://developer.mozilla.org/en-US/docs/Web/CSS/touch-action

0
répondu Gurpreet 2018-05-28 19:02:40

C'est la solution la plus simple que j'ai eu jusqu'à présent. Et croyez-moi j'ai essayé tous les autres, et c'est le plus facile. Il fonctionne grand sur les appareils Windows , qui pousse la page de la droite d'avoir de la place pour le scrollbar système et iOS appareils qui ne nécessitent pas d'espace pour leurs barres de défilement dans les navigateurs. Donc, en utilisant ceci, vous n'aurez pas besoin d'ajouter du rembourrage sur la droite pour que la page ne clignote pas lorsque vous masquer le débordement de le corps ou html avec css .

la solution est assez simple si vous y pensez. L'idée est de donner la fenêtre .scrollTop () la même position exacte au moment où un popup est ouvert. Changez également cette position lorsque la fenêtre redimensionne ( comme la position de défilement change une fois que cela se produit ).

alors on y va...

permet D'abord de créer la variable qui vous fera savoir que le popup est ouvert et l'appeler stopWindowScroll . Si nous ne le faisons pas, alors vous obtiendrez une erreur d'une variable non définie sur votre page et la définirez à 0 - comme non active.

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

permet maintenant de faire la fonction popup ouvrir sorcière peut être n'importe quelle fonction dans votre code qui déclenche quelque popup que vous utilisez comme un plugin ou personnalisé. Dans ce cas, ce sera un popup personnalisé simple avec un document simple sur la fonction de clic.

$(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);
});

Donc la prochaine chose que nous faisons est de créer la fonction de popup close, que je répète encore une fois peut être n'importe quelle fonction que vous avez déjà créé ou utilisez dans un plugin. La chose importante est que nous avons besoin de ces 2 fonctions pour définir la variable stopWindowScroll à 1 ou 0 pour savoir quand elle est ouverte ou fermée.

$(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);
});

permet alors de créer la fenêtre.fonction de défilement afin que nous puissions empêcher le défilement une fois le stopWindowScroll mentionné ci-dessus est réglé sur 1 active.

$(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);
    }
});

C'est ça. Aucun CSS requis pour cela de travailler, sauf vos propres styles pour la page. Cela a fonctionné comme un charme pour moi et j'espère qu'il vous aide et d'autres.

voici un exemple de travail sur JSFiddle:

js Fiddle Example

dites-moi si cela a aidé. Égard.

0
répondu Architect 2018-09-13 18:16:56

j'ai trouvé une meilleure façon, mais buggy, combinant l'idée de sdleihssirrhc:

window.onscroll = function() {
    window.scrollTo(window.scrollX, window.scrollY);
    //Or
    //window.scroll(window.scrollX, window.scrollY);
    //Or Fallback
    //window.scrollX=window.scrollX;
    //window.scrollY=window.scrollY;
};

Je ne l'ai pas testé, mais je vous le ferai savoir plus tard. Je suis sûr à 85% que ça marche sur les principaux navigateurs.

-4
répondu dsrdakota 2012-07-07 00:27:27

activer le CSS suivant avec JavaScript aidera. Je ne suis pas aussi bon que les autres, mais ça a marché pour moi.

body {
    position: fixed;
    overflow-y: scroll;
}
-4
répondu Cheyenne Forbes 2017-02-24 00:00:38