Using the following piece of code:
(function($){
$(window).on('scroll', function(){
var scroll_top = $(document).scrollTop();
if (scroll_top > 50 && scroll_top < 100) {
console.log(scroll_top);
}
});
})(jQuery)
Viewing the console shows me a range of numbers between 50 & 100 whilst I scroll up and down, as expected.
However, I need a way to log each number between 50 & 100 as I've scrolled. So that if I stop at 55 it would log 51, 52, 53, 54, 55.
I understand that this is because browsers run javascript and render the page at different speeds but is it at all possible?
var scroll_pos_at_mousedown;
var aa = function(){
$(window).on('scroll mouseup mousedown', function(e){
var scroll_top = $(document).scrollTop();
if(e.type == 'mousedown') {
var scroll_top1 = $(document).scrollTop();
if(scroll_top1 <= 50) {
scroll_pos_at_mousedown = 50;
} else if(scroll_top1 > 50 || scroll_top1 <= 500) {
scroll_pos_at_mousedown = scroll_top1;
} else {
scroll_pos_at_mousedown = 500;
}
console.log("scroll_top is "+scroll_top1);
}
console.log("current_scroll_top is " + scroll_pos_at_mousedown);
if (scroll_top > 50 && scroll_top < 500) {
if(e.type == "mouseup") {
var scroll_pos_at_mouseup = $(document).scrollTop();
console.log('scroll_pos_at_mouseup is '+scroll_pos_at_mouseup);
if(scroll_pos_at_mousedown<=500) {
for(i=scroll_pos_at_mousedown;i<=scroll_pos_at_mouseup;i++)
console.log(i);
}else {
for(i=scroll_pos_at_mouseup;i<=500;i++)
console.log(i);
}
}
}
});
};aa();
I have written this function keeping event mousedown and mouseup in mind. You can add keyup and keydown event as well and add it for up and down arrow keyCode. Hope this helps :)
I have a sidebar that becomes position:fixed when the bottom of the div is visible (followed this tutorial). My problem is I only need the JS to work if the screen size is more than or equal to 1025px.
I know I need something along the lines of if($(window).width() > 1025), but I can't figure out where that needs to be. I'm not great with JS so any help would be appreciated.
Demo
JS
$(function () {
if ($('.leftsidebar').offset()!=null) {
var top = $('.leftsidebar').offset().top - parseFloat($('.leftsidebar').css('margin-top').replace(/auto/, 0));
var height = $('.leftsidebar').height();
var winHeight = $(window).height();
var footerTop = $('#footer').offset().top - parseFloat($('#footer').css('margin-top').replace(/auto/, 0));
var gap = 100;
$(window).scroll(function (event) {
// what the y position of the scroll is
var y = $(this).scrollTop();
// whether that's below the form
if (y+winHeight >= top+ height+gap && y+winHeight<=footerTop) {
// if so, ad the fixed class
$('.leftsidebar').addClass('leftsidebarfixed').css('top',winHeight-height-gap +'px');
}
else if (y+winHeight>footerTop) {
// if so, add the fixed class
$('.leftsidebar').addClass('leftsidebarfixed').css('top',footerTop-height-y-gap+'px');
}
else
{
// otherwise remove it
$('.leftsidebar').removeClass('leftsidebarfixed').css('top','315px');
}
});
}
}
This should work:
var flag = false;
// This will keep on checking for window size while you are scrolling.
$(window).on("scroll", function() {
if (flag){
// Do whatever you want here
alert("hey");
}
});
$(window).on("resize", function() {
if ($(window).width() >= 1025){
flag = true;
} else {
flag = false;
}
})
From my comment: Just put that if($(window).width() > 1025) inside the function provided to the scroll event.
e.g.
$(window).scroll(function (event) {
if ($(window).width() > 1024) {
// what the y position of the scroll is
var y = $(this).scrollTop();
// whether that's below the form
if (y + winHeight >= top + height + gap && y + winHeight <= footerTop) {
// if so, ad the fixed class
$('.leftsidebar').addClass('leftsidebarfixed').css('top', winHeight - height - gap + 'px');
} else if (y + winHeight > footerTop) {
// if so, ad the fixed class
$('.leftsidebar').addClass('leftsidebarfixed').css('top', footerTop - height - y - gap + 'px');
JSFiddle: http://jsfiddle.net/TrueBlueAussie/3w5dt/31/
Notes:
not that 1 PX matters, but you did say > 1024px, hence changing 1025 to 1024 :)
First of all you should have a look at the jQuery documentation. The $.browser function was removed in jQuery 1.9. This can end up in serious problems in your code.
Just add something like the follwing code in the first if condition:
if (!msie6 && $('.leftsidebar').offset()!=null && $(window).width() > 1025 ) {
...
}
That should be all. If you want, that javascript should react on window resize just add something like the following
$(window).on('resize', function( event ) { /* code here */ }).trigger('resize');
if(screen.width >= 1024)
{
$(window).scroll(function (event) {
//Write your function code here
});
}
I hope it will help you.
I have the following code and I am trying to turn off the function when window resize is run, currently it just keeps running on window.resize.
function headerParallax(x) {
if (x ==="true"){
$(window).scroll(function() {
// Store scrollTop in variable
var scrollPos = $(window).scrollTop();
// var viewportHeight = $(window).height();
console.log(scrollPos + 'bgbottle1');
var bouncePos = ((-1 * (scrollPos - 75) * 1.5) + scrollPos).toFixed(2);
var bouncePos1 = ((-1 * (scrollPos - 150) * 1.25) + scrollPos).toFixed(2);
$(".bottle1").css({ 'background-position': "right " + bouncePos + 'px'});
if (scrollPos > 150){
$(".bottle2").css({ 'background-position': "left " + bouncePos1 + 'px'});
}
});
}else if(x === "false"){
alert("no");
}
}
$(window).resize(function(){
if ($(window).width() < 1200){
window.requestAnimationFrame(headerParallax("false"));
}
});
if ($(window).width() > 1200){
window.requestAnimationFrame(headerParallax("true"));
}
You can try something like this:
var _preflag = -1;
var _unbindScroll = function(){};
// it will be fired only once (when flag is changed)
function headerParallax(flag){
if (flag === _preflag){
return;
}
_preflag = flag;
if (flag){
// TODO adjust the UI for true
window.requestAnimationFrame(theCalculatedValue);
_unbindScroll(); // It's duplicate work to unbind scroll here, but there's no harm calling it :)
$(window).on('scroll', _onscroll);
// update the ubind scroll so that anyone can ubind it safely
_unbindScroll = function(){
$(window).off('scroll', _onscroll);
_unbindScroll = function(){};
};
} else {
// TODO adjust the UI for false
window.requestAnimationFrame(theCalculatedValue);
_unbindScroll(); // unbind scrolling, this is what you want, right?
}
function _onscroll(){
// TODO
}
}
function resize(){
// this will be fired multipe times, need to check it in sub functions to take it once
headerParallax($(window).width() < 1200);
}
$(window).resize(resize);
resize();
When you get to the limit of document, you can keep scrolling and can see an background behing the document before it bounces back (overscrolling).
How can I force the window to overscroll like this with javascript?
This is not the ultimate solution since I think the animation is imperfect and it's really only for desktops, but it can at least get you started. What I have done is increase the height of the body for animation on scroll.
$(document).on('scroll mousewheel', function (e) {
//Check for mousewheel scrolling down (or not used at all)
if (!e.originalEvent || !e.originalEvent.wheelDeltaY
|| e.originalEvent.wheelDeltaY < 0) {
if ($(window).height() + $(this).scrollTop() == $(this).height()) {
//Prevent simultaneous triggering of the animation
if (!$("body").data('bouncing')) {
$("body").height(function (_, h) { return h + 15; })
.data('bouncing', true);
$("body, html").animate({
'scrollTop': '+=15'
}, 125).animate({
'scrollTop': '-=15'
}, {duration: 125, complete: function () {
$(this).height(function (_, h) { return h - 15; })
.data('bouncing', false);
}});
}
}
}
}).on('keydown', function (e) {
//The "down" arrow; still bounces when pressed at the bottom of the page
if (e.which == '40') {
$(this).trigger('scroll');
}
});
I've been playing with this version that imitates the effect using a div, that slides in and out of view at the bottom of the page. If you have a high res monitor, you may need to increase the height of the main div to test it.
<div id="main" style="background:#f5f5f5;height:1000px"></div>
<div id="overscroll" style="background:#666666;height:120px"></div>
<script type="text/javascript">
var $doc = $(document);
$doc.ready(function () {
var $wnd = $(window),
$oscroll = $('#overscroll'),
block = false;
$wnd.bind('scroll', function () {
if (!block) {
block = true;
var scrollTop = $wnd.scrollTop(),
wndHeight = $wnd.height(),
docHeight = $doc.height();
try {
if (scrollTop + (wndHeight + 120) > docHeight) {
$oscroll.slideUp('slow');
}
else if ($oscroll.css('display') === 'none'
&& (scrollTop + (wndHeight + 120) < docHeight)) {
$oscroll.slideDown();
}
} finally {
block = false;
}
}
});
});
</script>
I have a div, with a scroll bar, When it reaches the end, my page starts scrolling. Is there anyway I can stop this behavior ?
You can inactivate the scrolling of the whole page by doing something like this:
<div onmouseover="document.body.style.overflow='hidden';" onmouseout="document.body.style.overflow='auto';"></div>
Found the solution.
http://jsbin.com/itajok
This is what I needed.
And this is the code.
http://jsbin.com/itajok/edit#javascript,html
Uses a jQuery Plug-in.
Update due to deprecation notice
From jquery-mousewheel:
The old behavior of adding three arguments (delta, deltaX, and deltaY)
to the event handler is now deprecated and will be removed in later
releases.
Then, event.deltaY must now be used:
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;
});
Demo
The selected solution is a work of art. Thought it was worthy of a 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();
});
};
This has been an ongoing inconvenience for me and this solution is so clean compared to other hacks I've seen. Curious to know how more about how it works and how widely supported it would be, but cheers to Jeevan and whoever originally came up with this. BTW - stackoverflow answer editor needs this!
UPDATE
I believe this is better in that it doesn't try to manipulate the DOM at all, only prevents bubbling conditionally...
$.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);
}
})
;
};
Works great in chrome and much simpler than other solutions... let me know how it fares elsewhere...
FIDDLE
You could use a mouseover event on the div to disable the body scrollbar and then a mouseout event to activate it again?
E.g. The HTML
<div onmouseover="disableBodyScroll();" onmouseout="enableBodyScroll();">
content
</div>
And then the javascript like so:
var body = document.getElementsByTagName('body')[0];
function disableBodyScroll() {
body.style.overflowY = 'hidden';
}
function enableBodyScroll() {
body.style.overflowY = 'auto';
}
As answered here, most modern browsers now support the overscroll-behavior: none; CSS property, that prevents scroll chaining. And that's it, just one line!
Here's a cross-browser way to do this on the Y axis, it works on desktop and mobile. Tested on OSX and 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});
I wrote resolving for this issue
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);
If I understand your question correctly, then you want to prevent scrolling of the main content when the mouse is over a div (let's say a sidebar). For that, the sidebar may not be a child of the scrolling container of the main content (which was the browser window), to prevent the scroll event from bubbling up to its parent.
This possibly requires some markup changes in the following manner:
<div id="wrapper">
<div id="content">
</div>
</div>
<div id="sidebar">
</div>
See it's working in this sample fiddle and compare that with this sample fiddle which has a slightly different mouse leave behavior of the sidebar.
See also scroll only one particular div with browser's main scrollbar.
this disables the scrolling on the window if you enter the selector element.
works like charms.
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");
});
You can inactivate the scrolling of the whole page by doing something like this but display the scrollbar!
<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();
}
});
Based on ceed's answer, here is a version that allows nesting scroll guarded elements. Only the element the mouse is over will scroll, and it scrolls quite smoothly. This version is also re-entrant. It can be used multiple times on the same element and will correctly remove and reinstall the handlers.
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");
});
};
One easy way to use is to add a class, such as scroll-guard, to all the elements in the page that you allow scrolling on. Then use $('.scroll-guard').scrollGuard() to guard them.
If you apply an overflow: hidden style it should go away
edit: actually I read your question wrong, that will only hide the scroll bar but I don't think that's what you are looking for.
I couldn't get any of the answers to work in Chrome and Firefox, so I came up with this amalgamation:
$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;
}
}
}