Here is the fiddle I'm working with: http://jsfiddle.net/fz5Yk/5/
As you can see, it has a one-page scrolling navigation. I want to achieve a highlighting effect (preferably using .animate function) to the headings in <strong> </strong> tags when scrolling to a section. Just scroll the page manually and you will see a highlighting in the navigation menu; item of the scrolled section, but I can't quite resolve the js codes in order to apply the same to the headings, and an intervention in it with .animate function seems much more difficult to me. Can you help me?
The plugin-page seems well-documented; https://github.com/davist11/jQuery-One-Page-Nav.
Just put an animation on the location you scroll to inside the end: definition;
$('#nav').onePageNav({
end: function() {
//I get fired when the animation is ending
}
});
Test update
$(window).scroll(function() {
var visible_start = window.pageYOffset;
var window_height = window.innerHeight;
var section3_height = $('#section-3').height();
var section3_start = $('#section-3')[0].offsetTop;
if ((visible_start - window_height >= section3_start) &&
$('#section-3').css('background-color', 'yellow');
}
});
Related
I'm trying to achieve a sliding scroll (like fullPage.js) by myself. I don't want to create a plugin either use a plugin. I only want to scroll/slide to a section when user trigger scroll (up and down!).
I've searched all over the internet and I do not know how to prevent the user from scrolling to replace standard scroll behavior by my animated scroll (desktop and mobile). I want to implement this animation inside a Bootstrap carousel item.
Summarizing, I have a carousel with several items, and each item will have a caption (outside the viewport). When the user scrolls down, then I will show the caption (like third slide here), and when the user scrolls up, I will scroll up and hide the caption.
Here is the CodePen with the carousel example running: link
This is what I get so far (I've got part of the code from StackOverflow)...
$(function(){
var _top = $(window).scrollTop();
var _direction;
$(window).scroll(function(){
var _cur_top = $(window).scrollTop();
if(_top < _cur_top)
{
_direction = 'down';
window.scrollTo(0, document.body.scrollHeight);
} else {
_direction = 'up';
window.scrollTo(0, 0);
}
_top = _cur_top;
console.log(_direction);
});
});
I get a very (very!) slow animation... It is not smooth at all.
I've tried this too:
$(document.body).on('DOMMouseScroll mousewheel', function (event) {
event.preventDefault();
if (event.originalEvent.wheelDelta > 0 || event.originalEvent.detail < 0) {
// Scroll up
$("html, body").animate({scrollTop: 0}, 400);
}
else {
// Scroll down
}
});
But, that code does not work and I get this error: [Intervention] Unable to preventDefault inside passive event listener due to the target being treated as passive.
I will be very thankful if you can help me, please!
Edited:
Someone helped me at "StackOverflow en espaƱol". Here is the solution!! Many thanks to #matahombres ;)
after a little advice. I'm working on my portfolio and I'm using a css transition to animate an element with some contact information which becomes active when the user scrolls up.
Within this element there is a figure class element called '.top-bar-avatar' which I have added a tool-tip and bounce animation too. This is all working but what I would like to achieve is for the tool-tip to automatically display and animation to fire when the figure is displayed within the web browser.
HTML
<li><figure class="top-bar-avatar"><img src="img/nick_avatar.png" alt="Top Bar Avatar Image Of Nick" title="Find Out More About Me" data-toggle="tooltip" data-placement="bottom"></figure></li>
JS
$('[data-toggle="tooltip"]').tooltip();
var lastScrollPosition = 0;
window.onscroll = function() {
var newScrollPosition = window.scrollY;
if (newScrollPosition < lastScrollPosition){
//upward code here
$('.top-bar').addClass('top-bar-animate');
}else{
//downward - code here
$('.top-bar').removeClass('top-bar-animate');
}
lastScrollPosition = newScrollPosition;
}
Tried a few different ways of doing this with yet to succeed. Any advice would be appreciated. Cheers in advance
I seem to have resolved this myself, i simply added and removed the display attribute and modified it's value within my existing code, see below.
Oh I also added a div id called 'profile-pic' to the image element, rather than focus on the figure class it's contained within.
var lastScrollPosition = 0;
window.onscroll = function() {
var newScrollPosition = window.scrollY;
if (newScrollPosition < lastScrollPosition){
//upward code here
$('.top-bar').addClass('top-bar-animate');
// display tool-tip when top-bar animates in
$('#profile-pic').tooltip('show');
}else{
//downward - code here
$('.top-bar').removeClass('top-bar-animate');
// hide tool-tip when top-bar animates out
$('#profile-pic').tooltip('hide');
}
lastScrollPosition = newScrollPosition;
}
I have a form that is sticky on every page, and I need it to stop being sticky when it reaches the top of the footer. I have this working properly, but I need it to become sticky again when scrolling back up the page. Anything glaringly wrong?
$(window).scroll(function(){
var footerTopPos = $('#footer-wrapper').offset().top;
var navBottomPos = $('#footer-form-wrapper').offset().top;
if(navBottomPos >= footerTopPos) {
$('#footer-form-wrapper').addClass('sticky');
} else {
$('#footer-form-wrapper').removeClass('sticky');
}
});
To clarify, the first part works perfectly. The css changes from "fixed" to "absolute" and the form stays in place. The problem is, I want it to revert back to "fixed" when you start scrolling back up the page (my else statement). This part does nothing at all.
Here is a rough jsfiddle to show the issue http://jsfiddle.net/L693f5bg/14/
--Edit--
To keep what you have started with the same and not use any other plugins you have to make sure you are declaring the variable outside the scroll function so that it doesn't get changed every time you scroll and change its position.
$(function () {
var footerTopPos = $('#footer-form-wrapper').offset().top;
$(window).scroll(function () {
var windowTopPos = $(window).scrollTop();
if (windowTopPos >= footerTopPos) {
$('#footer-form-wrapper').css('position', 'absolute');
$('#footer-form-wrapper').css('top', '0');
} else {
$('#footer-form-wrapper').css('position', 'fixed');
$('#footer-form-wrapper').css('bottom', '0');
$('#footer-form-wrapper').css('top', 'auto');
}
});
});
Updated your JSFiddle
Personally I recommend using Waypoints.js and the sticky elements plugin. It does everything and it's super clean and easy to implement. include the jquery.waypoints.js and the sticky plugin then initialize using:
var sticky = new Waypoint.Sticky({
element: $('#footer-wrapper')[0],
offset: '90%',
stuckClass: 'unstuck'
});
I updated the JSFiddle using the Waypoints.js plugin
Recently here, I asked a question to stick a bar element always to bottom-left of the container. It seems not possible using just css. So, I ended up using javascript. Here is the Working Fiddle
Giving highlights of the previous question:
Stick the bar element to bottom-left of the container
The bar should be in bottom-left, even the container is scrolled vertically or horizontally.
The bar should come over the horizontal scrollbar, if the horizontal scrollbar is present.
The above fiddle works fine and obeys all above cases, even when the window is resized.
Now, I have the same situation but the container will get resized because of animation button click but not window resize.
Since, I am animating for one second, I am calling the same code present in the window resize function while I clicked on the animating button. But doing so is somehow breaking and isn't following the above rules/requirements.
Here is the Fiddle. (not working)
Please help.
PS: Here is the link to previous question. (if someone wants brief understanding)
Again, I solved it. I was making things complicated. Where there was need of only bottom property, I was using top and resetting it. Lots of unneccessary action in the code.
Here is the code, which is working fine.
$(function () {
$('.content').width($('body').width() - 50);
});
var stickToBottom = function (parent) {
var bar = parent.querySelector('.bar');
var top = bar.offsetTop;
parent.addEventListener('scroll', function (e) {
var el = e.currentTarget;
bar.style.bottom = -el.scrollTop + "px";
bar.style.left = el.scrollLeft + "px";
});
}
var parent = document.querySelector('.parent');
stickToBottom(parent);
$('.clickme').click(function () {
$(this).toggleClass('active');
});
Thanks to rlemon for giving a idea in javascript chat room.
Working 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>