I added the parallax.js jQuery plugin and the effect works, but not properly. The background is zoomed in and the image is glitchy on scroll. I added additional variables listed in the documentation to fix those issues, and they work as expected. However, unexpectedly they also break my content which is created dynamically using JS in the '#sections' div, an empty div populated with a JavaScript object?
function parallaxBackground (){
var yPos = -(($window.scrollTop() - $this.offset().top) / 5);// Scroll speed
var coords = '1% '+ yPos + 'px';// Background position
$this.css({ backgroundPosition: coords });// Move the background
}
parallaxBackground();//Call parallaxBackground function
Any idea why this function would erase HTML content created using JS? The rest of the JS still works, its just the '#sections' div that stops working. Scroll, reveal, and hover effects are still intact. Here is a link to the code.
https://gist.github.com/flyspaceage/075dcf3a6d6bd65edf0f456036eb9bd8
Please read comment by FlySpaceAge for more info.
I ended up changing the script a bit and adding some variables from the parallax documentation. While this solution did fix the functionality, the background image is now zoomed in. While not perfect, this function did fix the initial problem I posted.
(function($){
$(document).ready(function(){
$('#sections').on('click', '.back-to-top', scrollToTop);
$('#jump-menu li').click(scrollToAnchor);
$('.parallax-window').parallax({imageSrc: '../images/background.png'});
});
function scrollToTop(event){
event.preventDefault();
$('html, body').animate({
scrollTop: 0
}, 500);
}
function scrollToAnchor(event){
event.preventDefault();
var target = $(this).attr('rel');
var offset = $(target).offset();
$('html, body').animate({
scrollTop: offset.top - 270
}, 500);
}
/* PARALLAX functionality*/
function parallaxBackground (){
var parallaxWidth = Math.max($(window).width() * 1, 1 ) | 0;
$('.parallax-window').width(parallaxWidth);
}
parallaxBackground();
})(jQuery);
Related
I have a list of items. When I click on one item (project) it opens (this is ok) and it scrolls to the top of the page (the wrong top!). The problem occurs when I have an opened item and I decide to open the one below: the top position is increased by the opened project height and the second project I click goes too far over the top.
Following the FIDDLE below: if I open project1 and then I click on project2, this goes on the wrong top. Same if I try to open any project below another opened one.
JS
$('.accordion-section-title').on('click', function () {
var idName = $(this).attr('id');
$('html, body').animate({
scrollTop: $("#" + idName).offset().top
}, 500);
});
Here's the FIDDLE
The problem seems to be the .slideUp() and .slideDown() methods are animated at the same time the window is scrolling. By the time the window has scrolled to the right Y coordinate, the accordion sections' heights have been altered, thus causing the window to end up in the wrong position.
I'm sure there are other ways to accomplish correct scroll positions, but my first thought was to store the initial Y positions once the page is loaded. This can be done this way:
$('.accordion-section-title').each(function() {
$(this).data('ypos', $(this).offset().top)
})
Each .accordion-section-title element will have its Y position stored in a data attribute called ypos. Later when you scroll the window, don't scroll to the elements position, but rather to its stored initial position. In other words, change scrollTop: $("#" + idName).offset().top to scrollTop: $("#" + idName).data('ypos'). Put together with your code it will look like the following:
$('.accordion-section-title').on('click', function(e) {
var idName = $(this).attr('id');
$('html, body').animate({
scrollTop: $("#" + idName).data('ypos') - 10
}, 500);
});
You can see how it plays out in this fiddle
I am building a Parallax website using SuperScrollorama which have some animation frame by frame using jquery and css3...
But after ending up doing so i am stuck in a problem, i am trying to navigate the pages using some scroll plugin...
I have tried Basic jquery using scrollTop event, using Jquery ScrollTo and using Tween Lite ScrollTo plugin to navigate through pages but nothing seems to work...
The issue i get after goggling it is if pages are pinned together as position:fixed; and pages doesnot scroll to that position and stuck between...
With Jquery ScrollTo, my code:-
$('.menus a').click(function(e){
e.preventDefault();
$.scrollTo(this.hash, 2000, {
easing:'easeInOutExpo',
offset:3000,
axis:'y',
queue:true
});
});
With basic scrollTop jquery, my code:-
$('a').bind('click',function(event){
var $anchor = $(this);
$('html, body').stop().animate({
scrollTop: $($anchor.attr('href')).offset().top
}, 1500,'easeInOutExpo');
event.preventDefault();
});
Currently my code works like this:- http://jsfiddle.net/tFPp3/6/
As you can see in my demo, the scroll stuck between before reaching the exact position through hash...
What is the solution if i have to play through the pinned elements in Superscrollorama?
You'll have to do 2 animations : one to reach the ancher offset and then, after superscrollorama added new element for animation and recalculate the document height, do the second animation to reach the correct key frame on that page (that you fixed at offset 3000 of that section).
$(function(){
var hashes = [];
$('.menus a').each(function(){
hashes.push(this.hash);
});
console.log('hashes:', hashes);
$('.menus a').click(function(e){
e.preventDefault();
var h = this.hash;
var pageTop = $(h).offset()['top'];
console.log('pageTop=',pageTop);
$.scrollTo( pageTop+1, 2000, {
easing:'easeInExpo',
axis:'y',
onAfter:function(){
setTimeout(function(){
console.log('hashes:', hashes);
var id = hashes.indexOf(h);
console.log('hashes['+(id+1)+']=', hashes[(id+1)]);
var nextPageTop = $(hashes[id+1]).offset()['top'];
console.log('nextPageTop=', nextPageTop);
var keyOffset = pageTop + 3000;
console.log('keyOffset=',keyOffset);
if(keyOffset < nextPageTop ){
$.scrollTo( keyOffset, 2000, {
easing:'easeOutExpo',
axis:'y'
});
}
},100);
}
});
});
});
Note that each section offset changes constantly so, before launching the second animation, we have to test that we are not scrolling till the next section again. We also need a little delay here to let superscrollorama make its sauce before testing respective offsets (saddly it doesn't seem to provide an event to do so).
I had the same issue as you. Here's how I went about fixing it....
First of all we know that Superscrollorama adds a spacer pin before your element, it sets the height of the element which defines how long the user has to scroll through a section (the duration)....So in theory all we have to do is add up all the pin heights that happen BEFORE the element you want to scroll to and then offset from the top of that element...
What I did was....
Find out what element you want to scroll to. Check how many supersrollorama-pin-spacers there are before that pin, work out the heights of all of the pins and then offset it to your initial scrollTo function.
pin = $('#pin-id').prev(); //find the spacer pin
prevPin = pin.prevAll('.superscrollorama-pin-spacer'); //find all the pins before this
heights = []; //create an array to store the pin heights
$.each(prevPin, function( index, value ) {
value = $(this).attr('height'); //get each height
heights.push(value); // push it to array
});
//use eval to join all the heights together
heights = eval(heights.join("+"));
Now we have the height so lets scroll to it.....
TweenMax.to($('html,body'),1, { scrollTop:heights, });
Good Luck! I hope this helps you.
I have had a similar issue and found that janpaepke on the superscrollorama project added an additional toggle to make this easier.
You can manually add the spacers so you don't need to make adjustments by setting the pushFollowers flag in your pin to false.
Example JS
controller.pin($('#pin-id'), 200, {
anim: new TimelineLite().append([TweenMax.fromTo( $('#pin-id'), 2, {css:{opacity: 1}}, {css:{opacity: 0}})]),
offset: 0,
pushFollowers: false
});
Example HTML
<div id="pin-id">
Bunch of Content
</div>
<div style="padding-top: 200px"></div>
You guys already helped me out a lot, I hope you can help me with this question to.
This is my website so far: http://stilld.nl/test/
Everything is working pretty good (need to do a lot of tidying up in my code though).
Please scroll down to the portfolio part. Click an item and the details appear beneath the portfolio. PERFECT!
PROBLEM: size you browser down to mobile format. Click a portfolio item. it doesn't scroll down far enough, because my portfolio items are now displayed beneath each other. They take up much more vertical space now!
WHAT I WANT: Is there a way to make code responsive? So something like: if screen size is smaller then 600 px THEN slide down 500px on click.
This is the code I'm using right now:
$(document).ready(function(){
$(".portfolio").click(function () {
if ($('#'+$(this).attr('target')).is(':visible')){
$('#'+$(this).attr('target')).slideUp();
} else {
$('.description').slideUp();
$('#'+$(this).attr('target')).slideDown();
$('html, body').animate({scrollTop: $('#targetWrapper').offset().top + 50 }, 600);
}
});
$(".close").click(function () {
$('.description').slideUp();
$('html, body').animate({scrollTop: $('#p_img').offset().top }, 600);
});
});
You should calculate the offset with either jQuery's .offset() or jQuery's .position().
What you could do for example is:
$(".portfolio").click(function () {
var offSetTarget = $('.description').position().top;
var scrollExtra = 0;
$('body').animate({
scrollTop: offSetTarget + scrollExtra
}, 600);
});
Where you can determine how much extra you want to scroll.
For example if you want to scroll just above the .portfolio, you can add: scrollExtra = -10; . Or if you want to scroll halfway, you could do: scrollExtra = $('.portfolio').height()/2;
I prepared a working example for you HERE.
To prove that it actually works, you can play with the window size here.
I hope that answers your question. Good luck!
Update
To implement it into your example, we would have to determine where to scroll to.
For illustrational purposes, I have chosen to do this with the divs #alldescriptions and #port_img1 in this example.
The jQuery for your website would then be:
$(document).ready(function() {
$(".portfolio").click(function () {
var offSetTarget = $('#alldescriptions').position().top;
var scrollExtra = 0;
if ($('#'+$(this).attr('target')).is(':visible')){
$('#'+$(this).attr('target')).slideUp();
} else {
$('.description').slideUp();
$('#'+$(this).attr('target')).slideDown();
$('body').animate({scrollTop: offSetTarget + scrollExtra }, 600);
}
});
$(".close").click(function () {
$('.description').slideUp();
$('body').animate({scrollTop: $('#port_img1').position().top }, 600);
});
});
Again, mind you that you can alter the exact scrolling location by giving var scrollExtra a different value.
You can find an implementation of this code here and a live fullscreen example here.
Please play around with the window size again so you can see it actually works with every screensize. Good luck!
You could detect the inner width of the screen and then set variables for the offset.
if(window.innerWidth <= 600) {
var offSet = 500;}
else{
var offSet = 600;}
Then replace this in your code:
$('html, body').animate({scrollTop: $('#targetWrapper').offset().top + 50 }, offSet);
BUT.... if you want to simplify your code, you could use CSS Transitions. Then just use jQuery to add and remove a class that triggers the Transition, using media querys to change the offset. It would also have less overhead.
I am using this code on a 'down' button to scroll text in an overflowed div.
var textHeight = text.outerHeight();
var pageDown = $('#page-down');
var pageUp = $('#page-up');
pageDown.bind('click', function () {
pageUp.fadeIn(500);
text.animate({ scrollTop: '+=' + textHeight + 'px' }, 500);
});
This is working nicely, but I need a method to determine when the scroll down button should disappear ... i.e. when the last content has appeared inside the div.
Is there a property or method to get the scrolled position within that div? Thanks
Here's a couple links you may want to look at:
http://yelotofu.com/2008/10/jquery-how-to-tell-if-youre-scroll-to-bottom/
http://www.mail-archive.com/jquery-en#googlegroups.com/msg22400.html
I feel stupid... this returns a number I can use:
console.log($('#text').attr('scrollTop'));
How can I make a div element move up and down the page when the user is scrolling the page? (where that element is always visible)
You want to apply the fixed property to the position style of the element.
position: fixed;
What browser are you working with? Not all browsers support the fixed property. Read more about who supports it, who doesn't and some work around here
http://webreflection.blogspot.com/2009/09/css-position-fixed-solution.html
Just for a more animated and cute solution:
$(window).scroll(function(){
$("#div").stop().animate({"marginTop": ($(window).scrollTop()) + "px", "marginLeft":($(window).scrollLeft()) + "px"}, "slow" );
});
And a pen for those who want to see: http://codepen.io/think123/full/mAxlb, and fork: http://codepen.io/think123/pen/mAxlb
Update: and a non-animated jQuery solution:
$(window).scroll(function(){
$("#div").css({"margin-top": ($(window).scrollTop()) + "px", "margin-left":($(window).scrollLeft()) + "px"});
});
using position:fixed alone is just fine when you don't have a header or logo at the top of your page. This solution will take into account the how far the window has scrolled, and moves the div when you scrolled past your header. It will then lock it back into place when you get to the top again.
if($(window).scrollTop() > Height_of_Header){
//begin to scroll
$("#div").css("position","fixed");
$("#div").css("top",0);
}
else{
//lock it back into place
$("#div").css("position","relative");
}
Here is the Jquery Code
$(document).ready(function () {
var el = $('#Container');
var originalelpos = el.offset().top; // take it where it originally is on the page
//run on scroll
$(window).scroll(function () {
var el = $('#Container'); // important! (local)
var elpos = el.offset().top; // take current situation
var windowpos = $(window).scrollTop();
var finaldestination = windowpos + originalelpos;
el.stop().animate({ 'top': finaldestination }, 1000);
});
});
Just add position: fixed; in your div style.
I have checked and Its working fine in my code.
You might want to check out Remy Sharp's recent article on fixed floating elements at jQuery for Designers, which has a nice video and writeup on how to apply this effect in client script