J'ai revu et testé les différentes fonctions pour empêcher le corps de faire défiler à l'intérieur d'un div et j'ai combiné une fonction qui devrait fonctionner.
$('.scrollable').mouseenter(function() {
$('body').bind('mousewheel DOMMouseScroll', function() {
return false;
});
$(this).bind('mousewheel DOMMouseScroll', function() {
return true;
});
});
$('.scrollable').mouseleave(function() {
$('body').bind('mousewheel DOMMouseScroll', function() {
return true;
});
});
- Cela arrête tout défilement là où je veux que le défilement soit toujours possible à l'intérieur du conteneur
- Cela ne se désactive pas non plus en cas d'absence de la souris
Des idées, ou de meilleures façons de faire cela?
Réponses:
Mise à jour 2: Ma solution est basée sur la désactivation totale du défilement natif du navigateur (lorsque le curseur est à l'intérieur du DIV) puis sur le défilement manuel du DIV avec JavaScript (en définissant sa
.scrollTop
propriété). Une approche alternative et meilleure de l'OMI serait de désactiver uniquement sélectivement le défilement du navigateur afin d'empêcher le défilement de la page, mais pas le défilement DIV. Découvrez la réponse de Rudie ci-dessous qui illustre cette solution.Voici:
Démo en direct: https://jsbin.com/howojuq/edit?js,output
Ainsi, vous définissez manuellement la position de défilement, puis vous évitez simplement le comportement par défaut (qui serait de faire défiler la DIV ou la page Web entière).
Mise à jour 1: Comme Chris l'a noté dans les commentaires ci-dessous, dans les versions plus récentes de jQuery, les informations delta sont imbriquées dans l'
.originalEvent
objet, c'est-à-dire que jQuery ne les expose plus dans son objet Event personnalisé et nous devons les récupérer à partir de l'objet Event natif à la place .la source
-e.detail
, testé dans Firefox (Mac, Linux), Safari (Mac) et Chromium (Linux)..detail
ne correspond pas au signe de.wheelData
(qui est ce que Chrome / IE a), nous devons donc l'inverser manuellement. Merci d'avoir corrigé ma réponse.if( e.originalEvent ) e = e.originalEvent;
if ( $(this)[0].scrollHeight !== $(this).outerHeight() ) { //yourcode }
ne s'exécutera que s'il y a une barre de défilement.Si vous ne vous souciez pas de la compatibilité avec les anciennes versions d'IE (<8), vous pouvez créer un plugin jQuery personnalisé, puis l'appeler sur l'élément débordant.
Cette solution a un avantage par rapport à celle proposée par Šime Vidas, car elle n'écrase pas le comportement de défilement - elle le bloque simplement le cas échéant.
la source
[Violation] Added non-passive event listener to a scroll-blocking 'mousewheel' event. Consider marking event handler as 'passive' to make the page more responsive.
Je pense qu'il est parfois possible d'annuler l'événement mousescroll: http://jsfiddle.net/rudiedirkx/F8qSq/show/
Dans le gestionnaire d'événements, vous aurez besoin de savoir:
d = e.originalEvent.deltaY, dir = d < 0 ? 'up' : 'down'
car un nombre positif signifie défilement vers le basscrollTop
pour le haut,scrollHeight - scrollTop - offsetHeight
pour le basSi vous êtes
top = 0
, oubottom = 0
,annuler l'événement:
e.preventDefault()
(et peut-être mêmee.stopPropagation()
).Je pense qu'il vaut mieux ne pas remplacer le comportement de défilement du navigateur. Ne l'annulez que le cas échéant.
Ce n'est probablement pas parfaitement xbrowser, mais cela ne peut pas être très difficile. Peut-être que la double direction de défilement de Mac est délicate cependant ...
la source
Utilisez la propriété CSS ci-dessous
overscroll-behavior: contain;
pour l'élément enfantla source
voyez si cela vous aide:
démo: jsfiddle
Éditer:
essaye ça:
la source
Une solution moins hacky, à mon avis, est de définir le débordement caché sur le corps lorsque vous passez la souris sur le div à défilement. Cela empêchera le corps de défiler, mais un effet de "saut" indésirable se produira. La solution suivante fonctionne autour de cela:
Vous pouvez rendre votre code plus intelligent si nécessaire. Par exemple, vous pouvez tester si le corps a déjà un remplissage et si oui, ajouter le nouveau remplissage à cela.
la source
Dans la solution ci-dessus, il y a une petite erreur concernant Firefox. Dans Firefox, l'événement "DOMMouseScroll" n'a pas de propriété e.detail, pour obtenir cette propriété, vous devez écrire 'e.originalEvent.detail' suivant.
Voici une solution de travail pour Firefox:
la source
voici une solution simple sans jQuery qui ne détruit pas le scroll natif du navigateur (c'est: pas de scrolling artificiel / laid):
Démo en direct: http://jsfiddle.net/ibcaliax/bwmzfmq7/4/
la source
Voici ma solution que j'ai utilisée dans les applications.
J'ai désactivé le débordement de corps et placé le html du site Web entier dans les div de conteneurs. Les conteneurs du site Web ont un débordement et l'utilisateur peut donc faire défiler la page comme prévu.
J'ai ensuite créé un div frère (#Prevent) avec un z-index plus élevé qui couvre l'ensemble du site Web. Comme #Prevent a un z-index plus élevé, il chevauche le conteneur du site Web. Lorsque #Prevent est visible, la souris ne survole plus les conteneurs du site Web, le défilement n'est donc pas possible.
Vous pouvez bien sûr placer un autre div, tel que votre modal, avec un z-index supérieur à #Prevent dans le balisage. Cela vous permet de créer des fenêtres pop-up qui ne souffrent pas de problèmes de défilement.
Cette solution est meilleure car elle ne cache pas les barres de défilement (effet de saut). Il ne nécessite pas d'écouteurs d'événements et est facile à mettre en œuvre. Cela fonctionne dans tous les navigateurs, bien qu'avec IE7 et 8, vous devez jouer (dépend de votre code spécifique).
html
css
jquery / js
désactiver / activer le défilement
la source
J'avais besoin d'ajouter cet événement à plusieurs éléments qui pourraient avoir une barre de défilement. Dans les cas où aucune barre de défilement n'était présente, la barre de défilement principale ne fonctionnait pas comme elle le devrait. J'ai donc apporté une petite modification au code @ Šime comme suit:
Désormais, seuls les éléments avec une barre de défilement empêcheront le défilement principal de commencer à s'arrêter.
la source
La version purement javascript de la réponse de Vidas
el$
est le nœud DOM du plan que vous faites défiler.Assurez-vous de ne pas attacher même plusieurs fois! Voici un exemple,
Attention , la fonction doit y avoir une constante, si vous réinitialisez la fonction à chaque fois avant de l'attacher, c'est à dire.
var func = function (...)
leremoveEventListener
ne fonctionnera pas.la source
Vous pouvez le faire sans JavaScript. Vous pouvez définir le style des deux div sur
position: fixed
etoverflow-y: auto
. Vous devrez peut-être rendre l'un d'entre eux plus haut que l'autre en définissant sonz-index
(s'ils se chevauchent).Voici un exemple de base sur CodePen .
la source
Voici le plugin qui est utile pour empêcher le défilement des parents lors du défilement d'un div spécifique et a un tas d'options avec lesquelles jouer.
Vérifiez le ici:
https://github.com/MohammadYounes/jquery-scrollLock
Usage
Déclenchez le verrouillage du défilement via JavaScript:
Déclenchez le verrouillage du défilement via le balisage:
Voir la démo
la source
il suffit de proposer cela comme solution possible si vous ne pensez pas que l'utilisateur aura une expérience négative du changement évident. J'ai simplement changé la classe de débordement du corps en hidden lorsque la souris était sur le div cible; puis j'ai changé le div du corps en débordement caché lorsque la souris part.
Personnellement, je ne pense pas que cela ait l'air mal, mon code pourrait utiliser toggle pour le rendre plus propre, et il y a des avantages évidents à rendre cet effet possible sans que l'utilisateur en soit conscient. C'est donc probablement la réponse hackish de dernier recours.
la source