Eu revisei e testei as várias funções para prevenir a habilidade do corpo de rolar enquanto dentro de uma div e combinei uma função que deve funcionar.
$('.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;
});
});
- Isso está interrompendo toda a rolagem onde eu quero que a rolagem ainda seja possível dentro do contêiner
- Isso também não é desativado ao deixar o mouse
Alguma ideia ou melhor maneira de fazer isso?
jquery
mousewheel
RIK
fonte
fonte
Respostas:
Atualização 2: Minha solução é baseada em desabilitar a rolagem nativa do navegador completamente (quando o cursor está dentro do DIV) e então rolando manualmente o DIV com JavaScript (definindo sua
.scrollTop
propriedade). Uma alternativa e melhor abordagem IMO seria apenas desativar seletivamente a rolagem do navegador para evitar a rolagem da página, mas não a rolagem DIV. Confira a resposta de Rudie a seguir, que demonstra essa solução.Aqui está:
Demonstração ao vivo: https://jsbin.com/howojuq/edit?js,output
Assim, você configura manualmente a posição de rolagem e, em seguida, evita o comportamento padrão (que seria rolar o DIV ou a página da web inteira).
Atualização 1: Como Chris observou nos comentários abaixo, nas versões mais recentes do jQuery, as informações delta estão aninhadas no
.originalEvent
objeto, ou seja, o jQuery não as expõe mais em seu objeto Event personalizado e, em vez disso, temos que recuperá-las do objeto Event nativo .fonte
-e.detail
, testado no Firefox (Mac, Linux), Safari (Mac) e Chromium (Linux)..detail
não corresponde ao sinal de.wheelData
(que é o que o Chrome / IE tem), então temos que invertê-lo manualmente. Obrigado por corrigir minha resposta.if( e.originalEvent ) e = e.originalEvent;
if ( $(this)[0].scrollHeight !== $(this).outerHeight() ) { //yourcode }
será executado apenas quando houver uma barra de rolagem.Se você não se preocupa com a compatibilidade com versões mais antigas do IE (<8), pode criar um plugin jQuery customizado e então chamá-lo no elemento overflowing.
Esta solução tem uma vantagem sobre a proposta da Šime Vidas, pois não sobrescreve o comportamento de rolagem - apenas o bloqueia quando apropriado.
fonte
[Violation] Added non-passive event listener to a scroll-blocking 'mousewheel' event. Consider marking event handler as 'passive' to make the page more responsive.
Acho que às vezes é possível cancelar o evento mousescroll: http://jsfiddle.net/rudiedirkx/F8qSq/show/
Dentro do manipulador de eventos, você precisa saber:
d = e.originalEvent.deltaY, dir = d < 0 ? 'up' : 'down'
porque um número positivo significa rolagem para baixoscrollTop
para cima,scrollHeight - scrollTop - offsetHeight
para baixoSe vocês são
top = 0
, oubottom = 0
,cancelar o evento:
e.preventDefault()
(e talvez atée.stopPropagation()
).Acho que é melhor não substituir o comportamento de rolagem do navegador. Cancele apenas quando aplicável.
Provavelmente não é perfeitamente xbrowser, mas não pode ser muito difícil. Talvez a direção de rolagem dupla do Mac seja complicada ...
fonte
Use a propriedade CSS abaixo
overscroll-behavior: contain;
para o elemento filhofonte
veja se isso ajuda você:
demo: jsfiddle
editar:
tente isto:
fonte
Uma solução menos hacky, na minha opinião, é definir o overflow oculto no corpo quando você passa o mouse sobre a div rolável. Isso evitará que o corpo role, mas ocorrerá um efeito de "salto" indesejado. A solução a seguir contorna isso:
Você pode tornar seu código mais inteligente, se necessário. Por exemplo, você pode testar se o corpo já tem um preenchimento e, em caso afirmativo, adicionar o novo preenchimento a ele.
fonte
Na solução acima existe um pequeno erro em relação ao Firefox. No Firefox "DOMMouseScroll", o evento não tem propriedade e.detail, para obter essa propriedade você deve escrever o seguinte 'e.originalEvent.detail'.
Aqui está uma solução funcional para o Firefox:
fonte
aqui uma solução simples sem jQuery que não destrói a rolagem nativa do navegador (isto é: nenhuma rolagem artificial / feia):
Demonstração ao vivo: http://jsfiddle.net/ibcaliax/bwmzfmq7/4/
fonte
Aqui está minha solução que usei em aplicativos.
Desativei o estouro do corpo e coloquei todo o html do site dentro do contêiner div. Os contêineres do site têm estouro e, portanto, o usuário pode rolar a página conforme o esperado.
Em seguida, criei um div irmão (#Prevent) com um Z-index mais alto que cobre todo o site. Como #Prevent tem um Z-index mais alto, ele se sobrepõe ao contêiner do site. Quando #Prevent está visível, o mouse não está mais pairando sobre os contêineres do site, portanto a rolagem não é possível.
Você pode, é claro, colocar outro div, como seu modal, com um índice z maior do que #Prevent na marcação. Isso permite que você crie janelas pop-up que não sofram de problemas de rolagem.
Esta solução é melhor porque não esconde as barras de rolagem (efeito de salto). Não requer ouvintes de eventos e é fácil de implementar. Ele funciona em todos os navegadores, embora com o IE7 e 8 você tenha que brincar (depende do seu código específico).
html
css
jquery / js
desabilitar / habilitar a rolagem
fonte
Eu precisava adicionar este evento a vários elementos que podem ter uma barra de rolagem. Para os casos em que nenhuma barra de rolagem estava presente, a barra de rolagem principal não funcionou como deveria. Então, fiz uma pequena alteração no código @ Šime da seguinte maneira:
Agora, apenas elementos com uma barra de rolagem impedirão que a rolagem principal pare.
fonte
Versão javascript pura da resposta de Vidas,
el$
é o nó DOM do plano que você está navegando.Certifique-se de não anexar o par várias vezes! Aqui está um exemplo,
Atenção , a função precisa ser uma constante, se você reinicializar a função todas as vezes antes de anexá-la, ou seja,
var func = function (...)
oremoveEventListener
não vai funcionar.fonte
Você pode fazer isso sem JavaScript. Você pode definir o estilo em ambos os divs para
position: fixed
eoverflow-y: auto
. Você pode precisar tornar um deles mais alto do que o outro, definindo seuz-index
(se eles se sobrepõem).Aqui está um exemplo básico no CodePen .
fonte
Aqui está o plugin que é útil para prevenir a rolagem dos pais ao rolar uma div específica e tem um monte de opções para brincar.
Confira aqui:
https://github.com/MohammadYounes/jquery-scrollLock
Uso
Acionar Scroll Lock via JavaScript:
Trigger Scroll Lock via Markup:
Ver demonstração
fonte
apenas oferecendo isso como uma solução possível se você não acha que o usuário terá uma experiência negativa na mudança óbvia. Eu simplesmente alterei a classe de estouro do corpo para oculta quando o mouse estava sobre a div de destino; então mudei o div do corpo para estouro oculto quando o mouse sai.
Pessoalmente, não acho que isso pareça ruim, meu código poderia usar alternância para torná-lo mais limpo, e há benefícios óbvios em tornar esse efeito possível sem que o usuário saiba. Portanto, esta é provavelmente a resposta de último recurso do hack.
fonte