jQuery animated scroll to anchor not working? - javascript

I thought I had resolved this issue but turns out i hadn't. Basically building a tumblr theme and something in my code is conflicting with the jquery animated scroll to top. I've tried removing things as I'm not entirely sure what it could be and thought it might be really obvious to somebody else?
Here is a link to my theme http://minori-theme.tumblr.com/ and a jsfiddle that I was following in order to animate the smooth scroll http://jsfiddle.net/YtJcL/1008/
The code I'm using is below and I'm just using a standard a link and id which are linking fine as it goes to the correct point its just not smooth scrolling.
$(document).ready(function() {
var hashTagActive = "";
$(".scroll").click(function (event) {
if(hashTagActive != this.hash) { //this will prevent if the user click several times the same link to freeze the scroll.
event.preventDefault();
//calculate destination place
var dest = 0;
if ($(this.hash).offset().top > $(document).height() - $(window).height()) {
dest = $(document).height() - $(window).height();
} else {
dest = $(this.hash).offset().top;
}
//go to destination
$('html,body').animate({
scrollTop: dest
}, 2000, 'swing');
hashTagActive = this.hash;
}
});
});
Edit: If anyone has a simpler alternative I'm open to suggestions?

Easing effect on your animate function won't work if you don't add easing libary. jQuery core does not have easing.
<script type="text/javascript" src="http://gsgd.co.uk/sandbox/jquery/easing/jquery.easing.compatibility.js"></s‌​cript>
Also you can define dynamic value to animate's timing based on your element's offset top value. This will make your animation smoother based on the current value.
Here is jsFiddle with smooth scrolling effect.
$(".scroll").click(function(event){
event.preventDefault();
var dest = 0;
var $target = $(this.hash);
var targetTop = $target.offset().top;
var remainTop = $(document).height() - $(window).height();
if( targetTop > remainTop){
dest = remainTop;
}else{
dest = targetTop;
}
// Dynamic value for timing
var dur = dest*1.2;
$('html,body').animate({scrollTop:dest}, dur,'easeInOutCubic');
});
And one last note, you should orgnize your code with using variables, these coding of your is hard to read and maintain.

The scroll works the first time, but not any time after that. Check through all the var's that get used to see if something is being kept.
EDIT:
The line
if(hashTagActive != this.hash)
will not bother with the jquery animation if you have already clicked "Back to top" because the hashTagActive is already #top. Thats why it works once but not twice.
EDIT 2:
Check out This fiddle for a way around it

Related

Perform action when object is visible in viewport

I have a div on my page, and I would like the background color to change when the viewer scrolls down to it.
How can I do this?
I would have used CSS3 with something like this...
var elemTop = $('div').offset().top;
$(window).scroll(function() {
if($(this).scrollTop() == elemTop) {
$('div').removeClass('hidden');
}
});
The commenter above is right. You should try something first and when you get stuck, the community will help you get unstuck. That said, here's a quick jquery to solve your problem.
$(document).ready(function(){
var offsetTop = $('#test').offset().top, //offset from top of element - element has id of 'test'
finalOffset = offsetTop - document.documentElement.clientHeight; //screen size
$(window).on('scroll',function(){
var whereAmI = $(document).scrollTop();
if(whereAmI >= offsetTop){
console.log("i've arrived at the destination");
}
})
})
Note that the above code executes the console.log() at every point past your requirement (meaning from there downwards). In case you want the execution to happen only one, you need to adapt the code a bit. One more note - if you're checking this in a fiddle, this document.documentElement.clientHeight needs to be adapted to work in an iframe. So test it on your local machine.

disable scrolling up past specific point

How can I make it so that a viewer cannot scroll up (past a specific point)?
Making it so a viewer cannot scroll is easy with:
body{
overflow: hidden;
}
but that disables scrolling down too.
Detailed description
what I want is some javascript/jquery code that will not allow scrolling up past a given parameter, while the viewer can still scroll up and down before that parameter is reached, but after it is reached they can only scroll up as long as it's not scrolling up past the given parameter
I have absolutely no idea how to go about doing this, any ideas?
You could set a physical point and say something like:
$(function() {
var scrollPoint = 200;
var scrolledPast = false;
$(window).scroll(function() {
$(window).scrollTop() > scrollPoint ? scrolledPast = true : '';
$(window).scrollTop() < scrollPoint && scrolledPast == true ? $(window).scrollTop(scrollPoint) : '';
}).scroll();
});
Fiddle
Although the disabling of scrolling seems a bit counter-intuitive-- why not just hide stuff off the page itself?

Fly-in Fly-out effect on scroll jquery css animation

I am trying to make the elements on my site fly-in and fly-out on scroll.
This is the effect I am looking for.
http://nizoapp.com/
The effect in the nizo site is done with jquery, I think
I have tried many different ways to get this effect working, with Skrollr, scrollorama, and jquery animate and with css transitions etc etc etc
I decided to use css transitions as mad by the "css animation cheat sheet" (google it)
After a lot of effort and some borrowed code, I have got it half working, as in, I can get the elements to fly-in on down scroll, but not to fly back out on up scroll.
This is a jsfiddle with it half working
http://jsfiddle.net/mrcharis/Hjx3Z/4/
The code is......
function isScrolledIntoView(elem) {
var docViewTop = $(window).scrollTop();
var docViewBottom = docViewTop + $(window).height();
var elemTop = $(elem).offset().top;
return ((elemTop <= docViewBottom) && (elemTop >= docViewTop));
}
$(window).scroll(function () {
$('.box').each(function (i) {
if (isScrolledIntoView(this)) {
$(this).addClass("slideRight");
}
});
});
// this is the function to check if is scroll down or up, but I cannot get it to trigger the fly in effect,
(function () {
var previousScroll = 0;
$(window).scroll(function () {
var currentScroll = $(this).scrollTop();
if (currentScroll > previousScroll){
// i figure to put the fly-in code here
}
else {
// and the fly-out code here
}
previousScroll = currentScroll;
});
}());
I have tried using another function (code chunk) to check if the scrolling is down or up, but i can't get it working with the existing code.
Any help to get this working would be awesome
Have a nice day
I will post the solution one day, if I can figure it out, sure someone else would like to know
The trick to knowing whether you're scrolling up or down is not to ask. Make it relational by using the top offset of the elements in question. Then it's as easy as > or <, for the most part.
Though if you do want to get the current direction you could always record the last scroll position and compare it with the current one.
var before = 0;
$(window).scroll(function(event){
var now = $(this).scrollTop();
if (now > before){
//on down code
} else {
//on up code
}
before = now;
});
Like the answer here suggests.
I like to trigger the events based on the screen size and the element position in the screen, so it doesn't matter whether it's up or down, it follows the same rules forwards and backwards. That way instead of asking up or down, it just asks if it's scrolling and executes it accordingly.
If you need me to make changes to my fiddle for you, just let me know what you want to happen. I only made the fiddle because of the horrible job they did on the tympanus.net example. You don't make a tutorial to accomplish a simple task 2 pages of js, that's unnecessary and it doesn't provide any instruction other than "hey, you want to do this? Then copy and paste these things I put together that have no clear course of action, and way too much code to digest quickly". Which doesn't help anyone learn.
After some code borrowing from tympanus.net and using the modernizer library I came up with this.
I tried different approaches as well but all of them turned out to have some flaws in them so I find best approach to be using the sample code and the already provided modernizer JS library.

javascript: animate scrolling when user scrolls

I want to animate page scrolling incrementally to different sections of the page when the user scrolls. So I wrote this code:
var $window = $(window);
var sectionHeight = $window.height();
var animating = false;
var dir;
// initialize page position (0)
var pagePos = $(window).scrollTop();
$(window).scroll(function() {
// current page position
var st = $(this).scrollTop();
// whether to animate up or down
dir = ((st > pagePos) ? '+=' : '-=');
// animate
if (animating == false) {
animating = true;
$('html, body').stop().animate({scrollTop: dir+sectionHeight},500, function() {
pagePos = $(window).scrollTop();
animating = false;
});
}
});
The problem is, I get a chained animation after my initial animation down, that animates the page back to the top. I'm not sure why, because it shouldn't animate unless 'animating' is set to false. It only gets set back to false when the animation is complete... right?
One potential fix, although I'm sure somebody can come up with a better solution, is to disable it for a set period of time after it scrolls.
Relevant code:
var ct = new Date().getTime();
if (animating == false && new Date().getTime() > ct + 10)
This will only allow the animation to happen if at least 11ms have passed. Seems to work for values as low as 2. You don't really notice any lag in scrolling but again, I would not consider this an ideal solution.
DEMO
I was able to get it to work, I still don't know why it wouldn't work as it was coded, but here is the solution that worked for me- I was inspired by #sachleen's answer. Thanks sachleen.
I moved the scroll animation into a separate function, then on the callback to the animation function I used a setTimeout with the same duration as the animation to call another function that simply changed the 'animating' boolean back to false.

jQuery fadeIn Messing up #hashtag Cross-linking

Ok, so I have a whole page hide / fadeIn effect happening with jQuery. Everything was working smoothly until I realized that the delay() + fadeIn() is causing my
Hashtag Links
to load with the scroll position at the top rather than where that #my_ID is on the page.
I know this is related to the whole page delay() // fadeIn() effects. It's not an option for me to ditch these effects, any way to circumvent this problem?
You can view the site (in production) at
http://valeriaentertainment.com.s66112.gridserver.com/
EDIT
This is the relevant jQuery code:
// #curtain DIV begins hidden then fades in after #bgImage (curtain) is loaded - prevents "ribbon" loading effect in Chrome
var allDone = false;
var url = $('.bgImage').attr('src');
var img = new Image();
img.onload = function() {
if (!allDone) {
$('#curtain').delay(1500).fadeIn(1000);
allDone = true;
}
};
setTimeout(img.onload, 2000); // show the hidden stuff after 5 seconds, image or no image
img.src = url;
At first glance at a gallery page, it looks like the entire page content is initially hidden. When the browser is loading the page, it will start looking for the element identified in the URL fragment; that element will be hidden or not visible and hence it won't have any useful position to scroll to and nothing happens to the scroll position.
I think the easiest thing to do would be to handle the scrolling yourself in the .fadeIn() callback:
Grab the fragment out of window.location.hash.
Find out where it is on the page with something like:
var y = $('#' + window.location.hash).offset().top;
Then scroll the page to that position:
$('html,body').attr('scrollTop', y);
You could even animate the scrollTop change if you wanted to get fancy.
Here's an example to get you started:
$('#curtain').delay(1500).fadeIn(1000, function() {
// Bail out if there is no hash.
if(!window.location.hash)
return;
// Convert the hash to an element and bail out
// if there is no such element.
var $e = $(window.location.hash);
if($e.length < 1)
return;
// And, finally, do what we're here to do.
$('html,body').attr('scrollTop', $e.offset().top);
});
If you wanted to animate the scrolling then you'd change the $('html,body').attr(...) part to something like this:
$('html,body').animate({ scrollTop: '+=' + $e.offset().top }, 'fast');

Categories

Resources