J'ai un div, avec une barre de défilement, Quand il arrive à la fin, ma page commence à défiler. Puis-je arrêter ce comportement de toute façon?
J'ai un div, avec une barre de défilement, Quand il arrive à la fin, ma page commence à défiler. Puis-je arrêter ce comportement de toute façon?
Réponses:
Vous pouvez désactiver le défilement de la page entière en faisant quelque chose comme ceci:
<div onmouseover="document.body.style.overflow='hidden';" onmouseout="document.body.style.overflow='auto';"></div>
J'ai trouvé la solution.
C'est ce dont j'avais besoin.
Et c'est le code.
http://jsbin.com/itajok/edit#javascript,html
Utilise un plug-in jQuery.
Mise à jour en raison d'un avis d'abandon
De jquery-mousewheel :
L'ancien comportement consistant à ajouter trois arguments (
delta,deltaXetdeltaY) au gestionnaire d'événements est désormais obsolète et sera supprimé dans les versions ultérieures.
Ensuite, event.deltaYdoit maintenant être utilisé:
var toolbox = $('#toolbox'),
height = toolbox.height(),
scrollHeight = toolbox.get(0).scrollHeight;
toolbox.off("mousewheel").on("mousewheel", function (event) {
var blockScrolling = this.scrollTop === scrollHeight - height && event.deltaY < 0 || this.scrollTop === 0 && event.deltaY > 0;
return !blockScrolling;
});
La solution choisie est une œuvre d'art. Je pensais que c'était digne d'un plugin ...
$.fn.scrollGuard = function() {
return this
.on( 'wheel', function ( e ) {
var event = e.originalEvent;
var d = event.wheelDelta || -event.detail;
this.scrollTop += ( d < 0 ? 1 : -1 ) * 30;
e.preventDefault();
});
};
Cela a été un inconvénient permanent pour moi et cette solution est si propre par rapport aux autres hacks que j'ai vus. Curieux de savoir comment cela fonctionne et à quel point il serait largement soutenu, mais bravo à Jeevan et à celui qui a initialement proposé cela. BTW - L'éditeur de réponses stackoverflow en a besoin!
METTRE À JOUR
Je pense que c'est mieux en ce sens qu'il n'essaye pas du tout de manipuler le DOM, cela empêche seulement le bouillonnement conditionnel ...
$.fn.scrollGuard2 = function() {
return this
.on( 'wheel', function ( e ) {
var $this = $(this);
if (e.originalEvent.deltaY < 0) {
/* scrolling up */
return ($this.scrollTop() > 0);
} else {
/* scrolling down */
return ($this.scrollTop() + $this.innerHeight() < $this[0].scrollHeight);
}
})
;
};
Fonctionne très bien en chrome et beaucoup plus simple que les autres solutions ... faites-moi savoir comment cela se passe ailleurs ...
wheelevent
Vous pouvez utiliser un événement mouseover sur le div pour désactiver la barre de défilement du corps, puis un événement mouseout pour l'activer à nouveau?
Par exemple, le HTML
<div onmouseover="disableBodyScroll();" onmouseout="enableBodyScroll();">
content
</div>
Et puis le javascript comme ceci:
var body = document.getElementsByTagName('body')[0];
function disableBodyScroll() {
body.style.overflowY = 'hidden';
}
function enableBodyScroll() {
body.style.overflowY = 'auto';
}
document.bodyplace.
Voici une façon multi-navigateurs de le faire sur l'axe Y, cela fonctionne sur ordinateur de bureau et mobile. Testé sur OSX et iOS.
var scrollArea = this.querySelector(".scroll-area");
scrollArea.addEventListener("wheel", function() {
var scrollTop = this.scrollTop;
var maxScroll = this.scrollHeight - this.offsetHeight;
var deltaY = event.deltaY;
if ( (scrollTop >= maxScroll && deltaY > 0) || (scrollTop === 0 && deltaY < 0) ) {
event.preventDefault();
}
}, {passive:false});
scrollArea.addEventListener("touchstart", function(event) {
this.previousClientY = event.touches[0].clientY;
}, {passive:false});
scrollArea.addEventListener("touchmove", function(event) {
var scrollTop = this.scrollTop;
var maxScroll = this.scrollHeight - this.offsetHeight;
var currentClientY = event.touches[0].clientY;
var deltaY = this.previousClientY - currentClientY;
if ( (scrollTop >= maxScroll && deltaY > 0) || (scrollTop === 0 && deltaY < 0) ) {
event.preventDefault();
}
this.previousClientY = currentClientY;
}, {passive:false});
scrollTop === maxScroll par scrollTop >= maxScroll. Cela semble bizarre sur 1 cas, c'était nécessaire
J'ai écrit pour résoudre ce problème
var div;
div = document.getElementsByClassName('selector')[0];
div.addEventListener('mousewheel', function(e) {
if (div.clientHeight + div.scrollTop + e.deltaY >= div.scrollHeight) {
e.preventDefault();
div.scrollTop = div.scrollHeight;
} else if (div.scrollTop + e.deltaY <= 0) {
e.preventDefault();
div.scrollTop = 0;
}
}, false);
e.currentTarget.
falsen'a pas besoin d'être spécifié addEventListenercar c'est la valeur par défaut. De plus, les comparaisons doivent être de simples inégalités ( >et <), pas >=ou <=.
Si je comprends bien votre question, vous voulez empêcher le défilement du contenu principal lorsque la souris est sur un div (disons une barre latérale). Pour cela, la barre latérale peut ne pas être un enfant du conteneur de défilement du contenu principal (qui était la fenêtre du navigateur), pour empêcher l'événement de défilement de remonter jusqu'à son parent.
Cela nécessite éventuellement des modifications de balisage de la manière suivante:
<div id="wrapper">
<div id="content">
</div>
</div>
<div id="sidebar">
</div>
Voyez que cela fonctionne dans cet exemple de violon et comparez cela avec cet exemple de violon qui a un comportement de sortie de souris légèrement différent de la barre latérale.
Voir aussi faire défiler un seul div particulier avec la barre de défilement principale du navigateur .
Comme répondu ici , la plupart des navigateurs modernes prennent désormais en charge la overscroll-behavior: none;propriété CSS, qui empêche le chaînage de défilement. Et c'est tout, juste une ligne!
overscroll-behavior: contain;.
cela désactive le défilement dans la fenêtre si vous entrez l'élément de sélection. fonctionne comme des charmes.
elements = $(".selector");
elements.on('mouseenter', function() {
window.currentScrollTop = $(window).scrollTop();
window.currentScrollLeft = $(window).scrollTop();
$(window).on("scroll.prevent", function() {
$(window).scrollTop(window.currentScrollTop);
$(window).scrollLeft(window.currentScrollLeft);
});
});
elements.on('mouseleave', function() {
$(window).off("scroll.prevent");
});
Vous pouvez désactiver le défilement de la page entière en faisant quelque chose comme ça mais affichez la barre de défilement!
<div onmouseover="document.body.style.overflow='hidden'; document.body.style.position='fixed';" onmouseout="document.body.style.overflow='auto'; document.body.style.position='relative';"></div>
$this.find('.scrollingDiv').on('mousewheel DOMMouseScroll', function (e) {
var delta = -e.originalEvent.wheelDelta || e.originalEvent.detail;
var scrollTop = this.scrollTop;
if((delta < 0 && scrollTop === 0) || (delta > 0 && this.scrollHeight - this.clientHeight - scrollTop === 0)) {
e.preventDefault();
}
});
Sur la base de la réponse de ceed, voici une version qui permet l'imbrication d'éléments protégés par défilement. Seul l'élément sur lequel se trouve la souris défilera et il défilera assez facilement. Cette version est également réentrante. Il peut être utilisé plusieurs fois sur le même élément et supprimera et réinstallera correctement les gestionnaires.
jQuery.fn.scrollGuard = function() {
this
.addClass('scroll-guarding')
.off('.scrollGuard').on('mouseenter.scrollGuard', function() {
var $g = $(this).parent().closest('.scroll-guarding');
$g = $g.length ? $g : $(window);
$g[0].myCst = $g.scrollTop();
$g[0].myCsl = $g.scrollLeft();
$g.off("scroll.prevent").on("scroll.prevent", function() {
$g.scrollTop($g[0].myCst);
$g.scrollLeft($g[0].myCsl);
});
})
.on('mouseleave.scrollGuard', function() {
var $g = $(this).parent().closest('.scroll-guarding');
$g = $g.length ? $g : $(window);
$g.off("scroll.prevent");
});
};
Un moyen simple d’utiliser consiste à ajouter une classe, par exemple scroll-guard, à tous les éléments de la page sur lesquels vous autorisez le défilement. Ensuite, utilisez $('.scroll-guard').scrollGuard()pour les garder.
Si vous appliquez un overflow: hidden style, il devrait disparaître
edit: en fait j'ai mal lu votre question, cela ne fera que masquer la barre de défilement mais je ne pense pas que ce soit ce que vous recherchez.
Je n'ai pas réussi à faire fonctionner l'une des réponses dans Chrome et Firefox, j'ai donc proposé cette fusion:
$someElement.on('mousewheel DOMMouseScroll', scrollProtection);
function scrollProtection(event) {
var $this = $(this);
event = event.originalEvent;
var direction = (event.wheelDelta * -1) || (event.detail);
if (direction < 0) {
if ($this.scrollTop() <= 0) {
return false;
}
} else {
if ($this.scrollTop() + $this.innerHeight() >= $this[0].scrollHeight) {
return false;
}
}
}