Ho un div, con una barra di scorrimento, quando arriva alla fine, la mia pagina inizia a scorrere. C'è comunque che posso fermare questo comportamento?
Ho un div, con una barra di scorrimento, quando arriva alla fine, la mia pagina inizia a scorrere. C'è comunque che posso fermare questo comportamento?
Risposte:
Puoi disattivare lo scorrimento dell'intera pagina facendo qualcosa del genere:
<div onmouseover="document.body.style.overflow='hidden';" onmouseout="document.body.style.overflow='auto';"></div>
Trovato la soluzione.
Questo è ciò di cui avevo bisogno.
E questo è il codice.
http://jsbin.com/itajok/edit#javascript,html
Utilizza un plug-in jQuery.
Aggiornamento a causa di avviso di deprecazione
Da jquery-mousewheel :
Il vecchio comportamento di aggiungere tre argomenti (
delta,deltaXedeltaY) al gestore di eventi è ora deprecato e verrà rimosso nelle versioni successive.
Quindi, event.deltaYora deve essere utilizzato:
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 soluzione scelta è un'opera d'arte. Ho pensato che fosse degno di 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();
});
};
Questo è stato un inconveniente continuo per me e questa soluzione è così pulita rispetto ad altri hack che ho visto. Curioso di sapere di più su come funziona e su quanto sarebbe ampiamente supportato, ma saluta Jeevan e chiunque abbia originariamente inventato questo. BTW - l'editor di risposte di stackoverflow ha bisogno di questo!
AGGIORNARE
Credo che questo sia meglio in quanto non cerca di manipolare affatto il DOM, previene solo il bubbling condizionatamente ...
$.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);
}
})
;
};
Funziona alla grande in Chrome e molto più semplice di altre soluzioni ... fammi sapere come se la cava altrove ...
wheelevento
Potresti usare un evento mouseover sul div per disabilitare la barra di scorrimento del corpo e quindi un evento mouseout per attivarlo di nuovo?
Ad esempio, l'HTML
<div onmouseover="disableBodyScroll();" onmouseout="enableBodyScroll();">
content
</div>
E poi il javascript in questo modo:
var body = document.getElementsByTagName('body')[0];
function disableBodyScroll() {
body.style.overflowY = 'hidden';
}
function enableBodyScroll() {
body.style.overflowY = 'auto';
}
document.body.
Ecco un modo cross-browser per farlo sull'asse Y, funziona su desktop e dispositivi mobili. Testato su 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. Sembra essere strano su 1 caso, era necessario
Ho scritto risolvendo questo 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.
falsenon è necessario specificarlo addEventListenerpoiché è l'impostazione predefinita. Inoltre, i confronti dovrebbero essere semplici disuguaglianze ( >e <), non >=o <=.
Se capisco correttamente la tua domanda, allora vuoi impedire lo scorrimento del contenuto principale quando il mouse è sopra un div (diciamo una barra laterale). Per questo, la barra laterale potrebbe non essere figlia del contenitore a scorrimento del contenuto principale (che era la finestra del browser), per evitare che l'evento di scorrimento si propaghi al suo genitore.
Ciò potrebbe richiedere alcune modifiche al markup nel modo seguente:
<div id="wrapper">
<div id="content">
</div>
</div>
<div id="sidebar">
</div>
Guarda che funziona in questo violino di esempio e confrontalo con questo violino di esempio che ha un comportamento di uscita del mouse leggermente diverso dalla barra laterale.
Vedi anche scorrere solo un particolare div con la barra di scorrimento principale del browser .
Come risposto qui , la maggior parte dei browser moderni ora supporta la overscroll-behavior: none;proprietà CSS, che impedisce lo scorrimento concatenato. Ed è tutto, solo una riga!
overscroll-behavior: contain;.
questo disabilita lo scorrimento sulla finestra se si entra nell'elemento selettore. funziona come un fascino.
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");
});
Puoi disattivare lo scorrimento dell'intera pagina facendo qualcosa di simile ma visualizza la barra di scorrimento!
<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();
}
});
Sulla base della risposta di ceed, ecco una versione che consente di annidare elementi protetti da scorrimento. Solo l'elemento su cui si trova il mouse scorrerà e scorre abbastanza facilmente. Anche questa versione è rientrata. Può essere utilizzato più volte sullo stesso elemento e rimuoverà e reinstallerà correttamente i gestori.
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 modo semplice per utilizzarlo è aggiungere una classe, ad esempio scroll-guard, a tutti gli elementi della pagina su cui consenti lo scorrimento. Quindi usa $('.scroll-guard').scrollGuard()per proteggerli.
Se applichi uno overflow: hiddenstile, dovrebbe scomparire
modifica: in realtà ho letto la tua domanda male, questo nasconderà solo la barra di scorrimento ma non credo che sia quello che stai cercando.
Non sono riuscito a ottenere nessuna delle risposte per funzionare in Chrome e Firefox, quindi ho pensato a questa fusione:
$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;
}
}
}