Eu tenho um div, com uma barra de rolagem, quando chega ao fim, minha página começa a rolar. Existe alguma maneira de interromper esse comportamento?
Eu tenho um div, com uma barra de rolagem, quando chega ao fim, minha página começa a rolar. Existe alguma maneira de interromper esse comportamento?
Respostas:
Você pode desativar a rolagem de toda a página fazendo algo assim:
<div onmouseover="document.body.style.overflow='hidden';" onmouseout="document.body.style.overflow='auto';"></div>
Encontrei a solução.
Isso é o que eu precisava.
E este é o código.
http://jsbin.com/itajok/edit#javascript,html
Usa um plug-in jQuery.
Atualização devido ao aviso de suspensão de uso
De jquery-mousewheel :
O antigo comportamento de adicionar três argumentos (
delta,deltaXedeltaY) ao manipulador de eventos agora está obsoleto e será removido em versões posteriores.
Então, event.deltaYagora deve ser usado:
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;
});
A solução selecionada é uma obra de arte. Achei que valia a pena um 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();
});
};
Isso tem sido um incômodo contínuo para mim e essa solução é tão limpa em comparação com outros hacks que já vi. Curioso para saber mais sobre como funciona e como seria amplamente apoiado, mas um brinde a Jeevan e a quem o criou originalmente. BTW - o editor de respostas stackoverflow precisa disso!
ATUALIZAR
Eu acredito que isso é melhor porque ele não tenta manipular o DOM, apenas evita o borbulhamento condicionalmente ...
$.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);
}
})
;
};
Funciona muito bem no cromo e muito mais simples do que outras soluções ... deixe-me saber como fica em outro lugar ...
wheelevento
Você poderia usar um evento mouseover no div para desativar a barra de rolagem do corpo e, em seguida, um evento mouseout para ativá-lo novamente?
Por exemplo, o HTML
<div onmouseover="disableBodyScroll();" onmouseout="enableBodyScroll();">
content
</div>
E então o javascript assim:
var body = document.getElementsByTagName('body')[0];
function disableBodyScroll() {
body.style.overflowY = 'hidden';
}
function enableBodyScroll() {
body.style.overflowY = 'auto';
}
document.body.
Esta é uma maneira para vários navegadores de fazer isso no eixo Y; ela funciona em desktops e dispositivos móveis. Testado em OSX e 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 by scrollTop >= maxScroll. Parece ser estranho em um caso, era necessário
Eu escrevi resolvendo este problema
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ão precisa ser especificado, addEventListenerpois é o padrão. Além disso, as comparações devem ser simples desigualdades ( >e <), não >=ou <=.
Se entendi sua pergunta corretamente, você deseja evitar a rolagem do conteúdo principal quando o mouse estiver sobre uma div (digamos uma barra lateral). Para isso, a barra lateral não pode ser filha do container de rolagem do conteúdo principal (que era a janela do navegador), para evitar que o evento scroll borbulhe para seu pai.
Isso possivelmente requer algumas alterações de marcação da seguinte maneira:
<div id="wrapper">
<div id="content">
</div>
</div>
<div id="sidebar">
</div>
Veja se está funcionando neste exemplo de violino e compare isso com este exemplo de violino, que tem um comportamento de saída do mouse ligeiramente diferente da barra lateral.
Consulte também rolar apenas um div específico com a barra de rolagem principal do navegador .
Conforme respondido aqui , a maioria dos navegadores modernos agora oferece suporte à overscroll-behavior: none;propriedade CSS, que evita o encadeamento de rolagem. E é isso, apenas uma linha!
overscroll-behavior: contain;.
isso desativa a rolagem na janela se você inserir o elemento seletor. funciona como amuletos.
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");
});
Você pode desativar a rolagem de toda a página fazendo algo assim, mas exiba a barra de rolagem!
<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();
}
});
Com base na resposta do ceed, aqui está uma versão que permite o aninhamento de elementos protegidos por rolagem. Somente o elemento sobre o qual o mouse está passando irá rolar, e ele rola de maneira bastante suave. Esta versão também é reentrante. Ele pode ser usado várias vezes no mesmo elemento e removerá e reinstalará corretamente os manipuladores.
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");
});
};
Uma maneira fácil de usar é adicionar uma classe, por exemplo scroll-guard, a todos os elementos da página em que você permite a rolagem. Em seguida, use $('.scroll-guard').scrollGuard()para protegê-los.
Se você aplicar um overflow: hiddenestilo, ele deve desaparecer
editar: na verdade eu li sua pergunta errado, isso só vai esconder a barra de rolagem, mas eu não acho que é isso que você está procurando.
Não consegui fazer com que nenhuma das respostas funcionasse no Chrome e no Firefox, então criei este amálgama:
$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;
}
}
}