web-dev-qa-db-fra.com

Comment désactiver le défilement temporairement?

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

Bien sûr, je pourrais faire une $("body").css("overflow", "hidden"); puis la remettre en mode automatique lorsque l'animation s'arrête, mais il serait préférable que la barre de défilement soit toujours visible mais inactive.

383
Olivier Lalonde

L'événement scroll ne peut pas être annulé. Mais vous pouvez le faire en annulant ces événements d'interaction:
Souris _ ​​&Appuyez sur le défilement et les boutons associés au défilement.

[ Démo de travail ]

// 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;  
}
659
gblazex

Faites-le simplement en ajoutant une classe au corps:

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

Ajoutez la classe, puis supprimez-la lorsque vous souhaitez réactiver le défilement, testé dans IE, FF, Safari et Chrome. 

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

Pour appareils mobiles , vous devrez gérer l'événement touchmove:

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

Et dissociez pour réactiver le défilement. Testé sous iOS6 et Android 2.3.3

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

Voici un moyen très simple de le faire:

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

C'est un peu nerveux dans IE6.

50
sdleihssirhc

La solution suivante est un JavaScript basique mais pur (pas de jQuery):

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

function enableScrolling(){
    window.onscroll=function(){};
}
26
Mohammad Anini

Cette solution maintiendra la position de défilement actuelle lorsque le défilement est désactivé, contrairement à certains qui ramènent l'utilisateur au sommet.

Il est basé sur la réponse de galambalazs , mais prend en charge les périphériques tactiles et est refactoré en tant qu’objet unique avec le wrapper du plugin jQery.

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

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

Il existe de nombreuses solutions permettant à ce problème d'afficher la barre de défilement, comme donner au conteneur une hauteur de 100% et un style overflow-y: scroll.

Dans mon cas, je viens de créer une div avec une barre de défilement que je montre 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 ces styles:

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

Cela montre une barre de défilement grise, espérons que cela aide les futurs visiteurs.

14
lisovaccaro

Je cherchais une solution à ce problème mais je n’étais satisfait d’aucune de ces solutions (au moment de la rédaction de cette réponse), j’ai donc proposé 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
Rajat Gupta

Selon le galambalazs post, j'ajouterais un support pour les appareils tactiles, nous permettant de toucher mais pas de défilement vers le haut ou le bas:

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

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

Une autre solution:

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

De cette façon, vous avez toujours une barre de défilement verticale, mais comme la plupart de mon contenu est plus long que la fenêtre d'affichage, tout va bien pour moi. Le contenu est centré avec un div séparé, mais sans remettre la marge dans le corps, mon contenu resterait à gauche.

Voici 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: un fond non défilable et aucun repositionnement du contenu à cause de la barre de défilement de gauche. Testé avec les versions actuelles de FF, Chrome et IE 10.

4
Marco

Que dis-tu de ç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
Dan

En fonction de ce que vous voulez réaliser avec le défilement supprimé, vous pouvez simplement réparer l'élément dont vous souhaitez supprimer le défilement (au clic, ou tout autre déclencheur que vous souhaitez désactiver temporairement).

Je cherchais une solution "temp no scroll" et cela répondait à mes besoins

faire un cours

.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é qu’il s’agissait d’une solution assez simple qui fonctionne bien sur tous les navigateurs et permet également une utilisation simple sur des appareils portables (c.-à-d. IPhones, tablettes, etc.). Puisque l'élément est temporairement fixé, il n'y a pas de défilement :)

REMARQUE! En fonction de l'emplacement de votre élément "contentContainer", vous devrez peut-être l'ajuster de la gauche. Ce qui peut facilement être fait en ajoutant une valeur css left à cet élément lorsque la classe fixed 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
axelra82

J'utilise showModalDialog pour afficher la page secondaire en tant que boîte de dialogue modale.

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

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

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

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

pour accéder aux éléments de la fenêtre principale à partir de la boîte de dialogue:

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

juste pour ceux qui cherchent showModalDialog :( après la 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
Zolfaghari

À partir de Chrome 56 et des autres navigateurs modernes, vous devez ajouter passive:false à l'appel addEventListener pour que preventDefault fonctionne. Donc, je l'utilise pour arrêter le défilement 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
Hokascha

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

Au lieu de cela, j'ai utilisé position: fixed; top: -scrollTop(); ci-dessous.

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

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

Ce code prend en compte les problèmes de largeur, hauteur, barre de défilement et saut de page.

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

  • largeur, lorsque la position est fixée, la largeur de l'élément html peut être inférieure à 100%
  • hauteur, comme ci-dessus
  • barre de défilement, lors du réglage de la position, le contenu de la page ne comporte plus de barre de défilement, même s'il en existait avant avant un saut de page horizontal
  • pagejump, lorsque la position est fixe, la page scrollTop n’est plus efficace, ce qui entraîne un saut de page vertical

Si quelqu'un a des améliorations à apporter au code de gel/déblocage de la page ci-dessus, faites-le-moi savoir afin que je puisse ajouter ces améliorations à mon projet.

2
seahorsepip

Je sais que c'est une vieille question, mais je devais faire quelque chose de très similaire et, après avoir cherché une réponse et essayé différentes approches, j'ai fini par utiliser une solution très simple.

Mon problème était très similaire, presque identique, la seule différence est que je n'avais pas à montrer la barre de défilement - je devais juste m'assurer que sa largeur serait toujours utilisée, pour que la largeur de la page ne change pas tant que ma superposition était affichée .

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

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

et après avoir glissé 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
user2430829

S'appuyant sur la réponse de Cheyenne Forbes, que j'ai trouvée ici via fcalderan: Il suffit de désactiver le défilement pour ne pas le cacher? et de corriger la disparition de la barre de défilement par Hallodom

CSS:

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

JS:

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

Ce code vous permet d'accéder au haut de la page, mais je pense que le code de fcalderan a une solution de contournement.

1
Quibble

Ce code fonctionnera sur Chrome 56 et plus (la réponse d'origine ne fonctionne plus sur Chrome).

Utilisez DomUtils.enableScroll() pour activer le défilement.

Utilisez DomUtils.disableScroll() pour désactiver le défilement.

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
PerrierCitror

J'ai le même problème, voici comment je le gère.

/* 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 cette aide.

1
sou yang

La méthode la plus simple est:

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

Pour l'annuler:

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

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

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

Cela est dû au fait que la barre de défilement a été supprimée et que la fenêtre d'affichage est devenue un peu plus large.

1
Daan

Voici ma solution pour arrêter le défilement (pas de jQuery). Je l'utilise pour désactiver le défilement lorsque le menu latéral apparaît.

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

Je mets 17px de padding-right pour compenser la disparition de la barre de défilement. Mais c'est également problématique, surtout pour les navigateurs mobiles. Résolu en obtenant la largeur de la barre selon this .

Tous ensemble dans ce stylo.

1
Josep81

J'ai eu un problème d'animation similaire sur les écrans mobiles mais pas sur les ordinateurs portables, lorsque j'essayais d'animer une div à l'aide de la commande animate de jquery. J'ai donc décidé d'utiliser une minuterie qui rétablissait la position de défilement de la fenêtre si souvent que le document paraissait statique. Cette solution fonctionnait parfaitement sur un appareil mobile à petit écran tel que Samsung Galaxy-2 ou iphone-5. 

Logique principale de cette approche : Le minuteur pour définir la position de défilement de la fenêtre sur la position de défilement d'origine doit être démarré avant la commande jquery animate, puis lorsque l'animation est terminée, nous devons effacer ce minuteur (original scroll position est la position juste avant l'animation départs).

J'ai trouvé à ma bonne surprise que le document semblait en réalité statique pendant la durée de l'animation si l'intervalle du minuteur était 1 millisecond, 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 dans ce message d'activation/désactivation du défilement, j'ai également constaté qu'une version modifiée du code comme ci-dessous fonctionnait.

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

Quelque chose que je viens de mettre en place:

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
akinuri

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

D'après ce violon: http://jsfiddle.net/dh834zgw/1/

le fragment de code suivant (utilisant jquery) désactivera le défilement 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
ling
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;
};
0
Văn Quyết

Mon point de vue sur cette question inclut également un problème de largeur du corps, car la page semble danser un peu lorsque 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
Fabio Nolasco

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. Cela fonctionne bien sur les périphériques Windows, ce qui pousse la page à partir de la droite pour laisser de la place pour la barre de défilement système et les périphériques IOS qui ne nécessitent pas d'espace pour leurs barres de défilement dans les navigateurs. Donc, en utilisant cela, vous n'aurez pas besoin d'ajouter de remplissage à droite pour que la page ne scintille pas lorsque vous masquez le débordement du corps ou du code HTML avec css.

La solution est assez simple si vous y réfléchissez. L'idée est de donner à window.scrollTop () la même position exacte au moment de l'ouverture d'une fenêtre contextuelle. Modifiez également cette position lorsque la fenêtre est redimensionnée (car la position de défilement change une fois que cela se produit).

Alors on y va ...

Commençons par créer la variable qui vous indiquera que le popup est ouvert et appelez-le stopWindowScroll. Si nous ne le faisons pas, vous obtiendrez une erreur d'une variable non définie sur votre page et définissez-la sur 0 - comme inactive.

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

Créons maintenant la fonction popup ouverte qui peut être n'importe quelle fonction de votre code qui déclenche le popup que vous utilisez en tant que plugin ou personnalisé. Dans ce cas, ce sera un simple popup personnalisé avec un simple document 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);
});

La prochaine chose que nous faisons est donc de créer la fonction popup de fermeture, ce que je répète peut être toute fonction que vous avez déjà créée ou que vous utilisez dans un plugin. L'important est que nous ayons besoin de ces 2 fonctions pour définir la variable stopWindowScroll sur 1 ou 0 afin de 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);
});

Créons ensuite la fonction window.scroll afin d’empêcher le défilement une fois que stopWindowScroll mentionné ci-dessus est défini sur 1 - comme actif.

$(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 tout. Aucune CSS requise pour que cela fonctionne, sauf vos propres styles pour la page. Cela a fonctionné comme un charme pour moi et j'espère que cela vous aidera et aidera les autres.

Voici un exemple de travail sur JSFiddle: 

Exemple JS Fiddle

Faites-moi savoir si cela a aidé. Cordialement.

0
Architect

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 la fermeture du popup release release:

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

Stocker la longueur du défilement dans une variable globale et la restaurer en cas de besoin!

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

la solution de galambalazs est géniale! Cela a fonctionné parfaitement pour moi dans Chrome et Firefox. Et il peut également être étendu pour empêcher tout événement par défaut de la fenêtre du navigateur . Supposons que vous exécutiez 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, dans votre application, disons que vous allez traiter vos propres événements, tels que la souris, le clavier, les événements tactiles, etc. 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 pouvez même désactiver le menu 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
Rafael

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

Pour plus d'informations. Regarde ça:-

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

0
Gurpreet

Vous pouvez bloquer le défilement de la barre d'espacement et masquer 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
santyas

Non, je n'irais pas avec la gestion d'événements parce que:

  • tous les événements ne sont pas garantis pour atteindre le corps,

  • en sélectionnant le texte et en le déplaçant vers le bas, le document défile,

  • si à la phase d’événement le détachement de qc va mal, vous êtes condamné.

J'ai mordu par ceci en faisant une action copier-coller avec une zone de texte masquée et devinez quoi, la page défilait à chaque fois que je fais une copie car en interne, je dois sélectionner la zone de texte avant d'appeler document.execCommand('copy').

Quoi qu'il en soit, c'est comme ça que je vais, remarquez la setTimeout():

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

Il y a un moment clignotant lorsque les barres de défilement disparaissent momentanément, mais c'est acceptable.

0
centurian