jQuery smooth scroll to anchor - javascript

I wrote a fairly simple smooth scrolling function using jQuery mousewheel extension, and having no former experience with $.mousewheel I ran into a problem.
Basically, once south delta is called, I call an $.animate function using scrollTop to a class of .anchor
HTML (simplified for question):
<div id="static-section" class="anchor"></div> <!-- width: 100%; height: 258px -->
<div id="alt-section" class="anchor"></div> <!-- width: 100%; height: 346px -->
jQuery:
$(document).ready(function() {
$("body").mousewheel(function(event, delta, deltaX, deltaY) {
if( delta > 0 ) {
console.log("North: " + delta);
}
else if( delta < 0 ) {
console.log("South: " + delta);
// ANIMATE TO ANCHOR FUNCTION
$("html,body").animate({scrollTop: $(".anchor").offset().top}, "slow");
}
return false;
});
});
So: my problem is that it only animates to the first instance of .anchor (which would be #static-section) I have tried doing scrollTop: $(".anchor").next().top which obviously doesn't work, though no errors appear, it still only animates to the first instance. My first guess was to use a for loop, and I tried it, but it didn't work (no errors on that either.) I've never really had a use for for loops before, so I'm unsure as to whether or not what I did was correct. Any help would be much appreciated!
Note: jsFiddle (with the same code as my website) does not portray the same thing that I've already accomplished, so no live demo available. If you guys need it, I'll provide the URL upon request. :-)

Something like this will step through the .anchor tags:
$(document).ready(function() {
var $anchor = $('.anchor');
$("body").mousewheel(function(event, delta, deltaX, deltaY) {
if( delta > 0 ) {
console.log("North: " + delta);
}
else if( delta < 0 ) {
console.log("South: " + delta);
// ANIMATE TO ANCHOR FUNCTION
$("html,body").animate({scrollTop: $anchor.offset().top}, "slow");
$anchor = $anchor.next('.anchor');
}
return false;
});
});

Related

jQuery .scroll() trigger with window height

I'm trying to trigger a function when the mouse wheel is spun, however the div is the height of the window, therefor isn't scrollable and isn't triggering my function. This is the code I am using to test if it works;
jQuery(document).ready(function($) {
$( document ).scroll(function () {
console.log('it works!');
});
});
You can see the full fiddle here; https://jsfiddle.net/8wr8p4ub/1/
If I change the height to an exact value, it triggers, however how can I achieve this when the element isn't scrollable?
You have to check with mousewheel event here and not document scroll. Since in your case document is not scrolling.
$(window).bind('mousewheel DOMMouseScroll', function(event){
if (event.originalEvent.wheelDelta > 0 || event.originalEvent.detail < 0) {
// scroll up
console.log("scroll up");
}
else {
// scroll down
console.log("scroll down");
}
});
* {
padding: 0;
margin: 0;
}
.hi {
height: 100vh; // Change to 1200px and see the output in the console.
width: auto;
background: #222;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="hi"></div>
You don't need to bother yourself about the scroll once the page content is not so long to bring it out. But from what i saw there, your code is fine, and it will work whenever the content exceeds the minimum page scroll
Better still, you can make use of the mousewheel event in JS
You need to use mousewheel event handler:
$('div').on('mousewheel', function(event){
if(event.originalEvent.wheelDelta / 120 > 0) {
console.log('scrolled up');
} else {
console.log('scrolled down');
}
});

jQuery Overflow: Hidden on Parent, Detect if Child is Actually On Visible

I'm having an issue with this jQuery that is blowing my mind. I've tried three different JS and jQuery functions people suggested online for accomplishing this and can't seem to get anything to work.
I'm trying to hide the class .arrow-up when .first is actually visible on the screen and hide the class .arrow-down when .last is visible on the screen.
Sounds simple enough, right?
Well the parent element has overflow: hidden on it (like most carousels–they really are from hell). Anyone know how to do this? I'd really appreciate any help, JS really isn't my strongest by any means...
Here's my current jQuery–
jQuery(document).ready(function ($) {
$(".arrow-down").bind("click", function (event) {
event.preventDefault();
$(".vid-list-container").stop().animate({
scrollTop: "+=300"
}, 300);
});
$(".arrow-up").bind("click", function (event) {
event.preventDefault();
$(".vid-list-container").stop().animate({
scrollTop: "-=300"
}, 300);
});
});
In this, .vid-list-container is the parent with overflow: hidden on it and .first and .last are both inside the container. The arrow classes are both outside of the container.
Built this pen for anyone who wants to play around with it.
http://codepen.io/seancrater/pen/waPNEW
Thanks!
This should work. Notice however that I used opacity:0, so the arrow can still be clicked. You need to change that!
function checkDownArrow() {
setTimeout(function() {
if($(".vid-list-container").scrollTop() != 0){
$('.arrow-up').css('opacity',1);
}
if(($(".vid-list-container").scrollTop() + $(".vid-item").height()+5) >= $(".vid-item").length * $(".vid-item").height()) {
$('.arrow-down').css('opacity',0);
}
},350);
}
function checkUpArrow() {
setTimeout(function() {
if($(".vid-list-container").scrollTop() == 0){
$('.arrow-up').css('opacity',0);
}
if(($(".vid-list-container").scrollTop() + $(".vid-item").height()+5) < $(".vid-item").length * $(".vid-item").height()) {
$('.arrow-down').css('opacity',1);
}
},350);
}
checkDownArrow();
checkUpArrow();
jQuery(document).ready(function ($) {
$(".arrow-down").bind("click", function (event) {
event.preventDefault();
$(".vid-list-container").stop().animate({
scrollTop: "+=173"
}, 300);
checkDownArrow();
});
$(".arrow-up").bind("click", function (event) {
event.preventDefault();
$(".vid-list-container").stop().animate({
scrollTop: "-=173"
}, 300);
checkUpArrow();
});
});
EDIT
Okay, I see you have a different problem... may I suggest using a different approach? Something like this.
HTML:
<div class="outer-wrapper">
<div class="inner-wrapper">
<div class="vid-item">
...
</div>
<div class="vid-item">
...
</div>
</div>
</div>
CSS:
.outer-wrapper {width:200px; height:150px; overflow:hidden;}
.inner-wrapper {height:auto; margin-top:0;}
.vid-item {width:200px; height:150px;}
JS:
var itemHeight = $('.vid-item').first().height();
var wrapperHeight = $('.inner-container').height();
$(".arrow-down").bind("click", function (event) {
event.preventDefault();
var margin = parseInt($('.inner-container').css('margin-top'));
if(itemHeight - margin > wrapperHeight) {
$('.inner-container').css('margin-top', (itemHeight-wrapperHeight) + 'px');
$('.arrow-down').addClass('hidden');
}
else {
$('.inner-container').css('margin-top', (margin-itemHeight) + 'px');
}
$('.arrow-up').removeClass('hidden');
});
$(".arrow-up").bind("click", function (event) {
event.preventDefault();
var margin = parseInt($('.inner-container').css('margin-top'));
if(margin + itemHeight >= 0) {
$('.inner-container').css('margin-top', '0');
$('.arrow-up').addClass('hidden');
}
else {
$('.inner-container').css('margin-top', (margin+itemHeight) + 'px');
}
$('.arrow-down').removeClass('hidden');
});

Disable scroll, animation, then enable scroll again

(first question so be nice :) )
I'm trying to disable scroll, animate a div, then re-enable scrolling. So far I have accomplished the first two parts of this incredible quest, but alas, I cannot seem to get it to scroll again.
I am using lockScroll() and unlockScroll() functions defined by JeanValjean on How to programmatically disable page scrolling with jQuery
Any help would be much appreciated. Please see demo http://jsfiddle.net/Chris_James/1xxL5dnp/6/
jQuery(document).ready(function(){
$(window).scroll(function(){
var p = $( ".testi" );
var offset = p.offset();
if ($(this).scrollTop() > offset.top - $(window).height()/2) {
lockScroll();
$('.testi').addClass( 'testishow' );
setTimeout(function(){
$('.testimonial').fadeIn('fast');
unlockScroll();
},700);
}
})
});
jQuery(document).ready(function(){
$(window).scroll(function(){
var p = $( ".testi" );
var offset = p.offset();
if ($(this).scrollTop() > offset.top - $(window).height()/2) {
lockScroll();
$('.testi').addClass( 'testishow' );
setTimeout(function(){
$('.testimonial').fadeIn('fast', function() {
unlockScroll();
});
},700);
}
})
Like Good.luck recommended, you can you use callbacks for unlocking (Well, I was a few seconds to late...). I think you don't have to declare a function just unlockScroll.
The lock/unlockScroll() methods seems to a bit to be overweight.
I would recommend cubbius answer with an "overflow: hidden" style for the html element.
Make a function out of your current scroll event and unlock it with:
$(window).off("scroll touchmove mousewheel", function () {
$(window).on("click", yourScrollMethod);
})
Solution - adding a class (scrolllocked) to if statement, and checking for it (with &&). Simples. http://jsfiddle.net/Chris_James/1xxL5dnp/6/
if ($(this).scrollTop() > offset.top - $(window).height()/2 && !p.hasClass("scrollLocked")) {
lockScroll();
p.addClass("scrollLocked");
$('.testi').addClass( 'testishow' );
You can use function callbacks for this e.g.
$('.testimonial').fadeIn('fast', function(){
unlockScroll();
});
In this case function unlockScroll() will execute only after fadeIn finished it's animation.
UPD: Added Fiddle

jQuery Highlight Nav links on scroll not working

I'm extremely new to JavaScript so I apologize in advance. I'm trying to create a one page html document for a school project using a list of links for navigation that change when the anchor is scrolled to. I've tried various different methods found on Jfiddle and through stackoverflow. This is the method I am trying now: http://jsfiddle.net/m2zQE/
var topRange = 200, // measure from the top of the viewport to X pixels down
edgeMargin = 20, // margin above the top or margin from the end of the page
animationTime = 1200, // time in milliseconds
contentTop = [];
$(document).ready(function () {
// Stop animated scroll if the user does something
$('html,body').bind('scroll mousedown DOMMouseScroll mousewheel keyup', function (e) {
if (e.which > 0 || e.type == 'mousedown' || e.type == 'mousewheel') {
$('html,body').stop();
}
});
// Set up content an array of locations
$('#nav').find('a').each(function () {
contentTop.push($($(this).attr('href')).offset().top);
});
// Animate menu scroll to content
$('#nav').find('a').click(function () {
var sel = this,
newTop = Math.min(contentTop[$('#nav a').index($(this))], $(document).height() - $(window).height()); // get content top or top position if at the document bottom
$('html,body').stop().animate({
'scrollTop': newTop
}, animationTime, function () {
window.location.hash = $(sel).attr('href');
});
return false;
});
// adjust side menu
$(window).scroll(function () {
var winTop = $(window).scrollTop(),
bodyHt = $(document).height(),
vpHt = $(window).height() + edgeMargin; // viewport height + margin
$.each(contentTop, function (i, loc) {
if ((loc > winTop - edgeMargin && (loc < winTop + topRange || (winTop + vpHt) >= bodyHt))) {
$('#nav li')
.removeClass('selected')
.eq(i).addClass('selected');
}
});
});
});
I'm still not having any luck. I've already searched to see if I could debug the problem and have tried changing the order of the code as well as the order of calling jquery.
Here is a link to the site: https://googledrive.com/host/0BwvPQbnPrz_LMlZDeGlFY2Yydmc/index.html
I used html5boilerplate as a starting point.Thank you in advance.
Don't have much time to look into your code, but when I input the line
Math.min(contentTop[$('#nav a').index($(this))], $(document).height() - $(window).height())
into the console of developer tools, it return NaN.
So I guess the problem is you don't have your scrollTop correctly set.
I suggest you give each element an id and try:
$('html, body').animate({
scrollTop: $("#elementID").offset().top
}, 2000);
or if you insist not giving id,
$('html, body').animate({
scrollTop: $("#container-fulid:nth-child(2)").offset().top
}, 2000);
but notice that this is not working on all browser as the nth-child selector is a CSS3 selector.
Or, if you know how to correctly use other's work, you may try to use bootstrap 3.0, where there is already a function named scrollspy included, which do exactly the thing you are doing.
http://getbootstrap.com/javascript/#scrollspy

Automatically Scroll Page from Top to Bottom, then Back Up (and Repeat)

I'm trying to figure out how to, upon pageload, automatically scroll to the bottom of a page (which has been described sufficiently here) and then scroll back up automatically upon reaching the bottom of the page. I can find the automatic scrolling to the bottom, but I can't figure out how to identify when I'm at the bottom of the page, and how to scroll back up when I am. I'd do this using generic Javascript (or JQuery).
Thanks in advance!
Try this:
http://jsfiddle.net/yjYJ4/
$('html, body').animate({ scrollTop: $(document).height() - $(window).height() }, 1000, function() {
$(this).animate({ scrollTop: 0 }, 1000);
});
You can view the demo in full screen here: http://jsfiddle.net/yjYJ4/embedded/result/
Change the number "1000" if you want to increase or decrease speed.
Works fine in Chrome, Firefox and IE 6-9.
EDIT:
If you need it to repeat forever (not recommended...) you could do like this: http://jsfiddle.net/QUCWe/
here is the example using Pure JavaScript
<script type="application/javascript">
var Height = document.documentElement.scrollHeight;
var currentHeight = 0;
var bool = true;
var step = 5;
var speed = 10;
var interval = setInterval(scrollpage, speed)
function scrollpage() {
if (currentHeight < 0 || currentHeight > Height)
bool = !bool;
if (bool) {
window.scrollTo(0, currentHeight += step);
} else {
// if you don't want to continue scroll
// clearInterval(interval) use clearInterval
window.scrollTo(0, currentHeight -= step);
}
}
</script>
<style type="text/css">
#top {
border: 1px solid black;
height: 10000px;
}
#bottom {
border: 1px solid red;
}
</style>
<div id="top">top</div>
<div id="bottom">bottom</div>
You can pass a function as an argument, which will be called when the end has reached. I've just written a jQuery plugin for this purpose. Fiddle: http://jsfiddle.net/kKaWZ/
(function($){
$.fn.downAndUp = function(time, repeat){
var elem = this;
(function dap(){
elem.animate({scrollTop:elem.outerHeight()}, time, function(){
elem.animate({scrollTop:0}, time, function(){
if(--repeat) dap();
});
});
})();
}
})(jQuery);
$("html").downAndUp(2000, 5)
Be aware that the suggested infinite scroll JSFiddle code will work in firefox however will not work in Chrome/Chromium without a valid
<!DOCTYPE html>
tag at the start of ones page. Per This Answer
$("body").animate({ scrollTop: '1000' }, 500, function(){
$("body").animate({ scrollTop: '0' }, 500, function(){
$("body").animate({ scrollTop: '1000' }, 500);
});
});

Categories