I wish someone could help me, I'm a little bit irked about this problem since I've been resolving other issues with this scroll behavior that I'm trying to implement on this site... as you see my sub-menu (on the left) follows the window position as you scroll or you can click any option on the sub-menu wich will trigger an animation, well what seems to be the problem is that everytime I click a second time it won't work, until I re-click it, it will work...
Here's my code
Variables
var startDistance = 210;
var $scrollingDiv = $("#sub-menu");
var position = $("#footer").position();
var height = $("#sub-menu").height();
var pos = position.top - (height + 460);
This is to differ between users and animation scroll
$("body,html").bind("scroll mousedown DOMMouseScroll mousewheel keyup", function(e){
if ( e.which > 0 || e.type === "mousedown" || e.type === "mousewheel"){
if($(window).scrollTop() > startDistance && $(window).scrollTop() < pos) {
$scrollingDiv.stop().animate({
paddingTop: ($(window).scrollTop() - 75) + "px"
}, 'slow');
}
if($(window).scrollTop() == 0) {
$scrollingDiv.stop().animate({
paddingTop: 0
}, 'slow');
}
}
});
Click behavior
$("#sub-menu ul li a").live('click', function(ev) {
var $anchor = $(this);
console.log($anchor.attr('href'));
$('html, body').stop().animate({
scrollTop: $($anchor.attr('href')).offset().top
}, 1500,'easeInOutExpo', function() {
$scrollingDiv.stop().animate({
paddingTop: ($($anchor.attr('href')).offset().top - 556) + "px"
}, 'slow');
});
event.preventDefault();
});
It might be the silliest thing but I've been watching my screen for last hour w/o being able to realize what's going on.
Edit: I'm posting my scroll code behavior too because I feel that It might be a global problem and not only related to my click code
Thank you in advance!
[22:00:25.137] ReferenceError: event is not defined # http://altivamedia.com/pruebas/romulos/wp/wp-content/themes/romulos/_/js/functions.js:45
You've accidentally wrote event instead of ev:
});
event.preventDefault();
});
Since event hasn't been defined a ReferenceError gets thrown. Simply use the correct variable:
});
ev.preventDefault();
});
Remark
In order to find such errors on your own use your browser's error console.
Related
Animation on scroll function is working fine on desktop view but it mess up the scrolling and scroll to random sections when I switch to mobile view and uses touch to scroll the screen. This is my animate on scroll function :
$(window).scroll(function() {
$('.skillbar').each(function(i){
if($(window).scrollTop() + $(window).height() > $(this).offset().top ){
jQuery(this).find('.skillbar-bar').animate({
width:jQuery(this).attr('data-percent')
},6000);
}
});
});
If I use the windows on scroll function, it mess up the mobile view. Please help to solve this issue so that animate on scroll can work on both mobile view with touch scroll and desktop view without messing the scroll.
For more Information these are the other scroll events:
(function($) {
"use strict"; // Start of use strict
// jQuery for page scrolling feature - requires jQuery Easing plugin
$('a.page-scroll').bind('click', function(event) {
var $anchor = $(this);
$('html, body').stop().animate({
scrollTop: ($($anchor.attr('href')).offset().top - 54)
}, 1250, 'easeInOutExpo');
event.preventDefault();
});
// Highlight the top nav as scrolling occurs
$('body').scrollspy({
target: '#mainNav',
offset: 80
});
// Closes the Responsive Menu on Menu Item Click
$('#navbarResponsive>ul>li>a').click(function() {
$('#navbarResponsive').collapse('hide');
});
// jQuery to collapse the navbar on scroll
$(window).scroll(function() {
if ($("#mainNav").offset().top > 100) {
$("#mainNav").addClass("navbar-shrink");
} else {
$("#mainNav").removeClass("navbar-shrink");
}
});
})(jQuery); // End of use strict
EDIT
Since this is the same function for both events...
Maybe calling it on the same handler and use an or to trigger only once will do the trick.
$(window).on("touchmove scroll", function(e) {
// Do the function on ONLY ONE of the two event.
if(e.type=="touchmove" || e.type=="scroll"){
$('.skillbar').each(function(i){
if($(window).scrollTop() + $(window).height() > $(this).offset().top ){
jQuery(this).find('.skillbar-bar').not(".triggered").addClass("triggered").animate({
width:jQuery(this).attr('data-percent')
},6000);
}
});
}
});
EDIT
I've added a subtility using a triggered class.
.not(".triggered").addClass("triggered")
One the first iteration of the .each() function, none of the skillbar-bar has the trigered class.
So let's add it! Then trigger the animation.
On the second and all next iterations, the triggered class removes all skillbar-bar which already have the triggered class out of the collection.
This prevent the animate() function to be fired more than once on each skillbar-bar.
I think this was the issue.
Let me know if it works !
I am using some code from www.css-tricks.com that can be used to animate local scrolling to a page anchor. Here is the code snippet:
$("class-name-here").on("click", function() {
var $target = $(this.hash);
$target = $target.length && $target
|| $('[name=' + this.hash.slice(1) +']');
if ($target.length) {
var targetOffset = $target.offset().top;
$('html,body')
.animate({scrollTop: targetOffset}, 1500, "easeOutQuint");
return false;
}
});
I have tried using a variety of times for the animation duration, but when I click the link, the page does scroll correctly, but after the scroll reaches the destination, the animation continues. In other words, it scrolls, but after the animation seems complete, if you try to scroll away manually, the page animates itself to that location again for about half a second.
Is there something wrong with the snippet / has anyone seen this before?
I found an example where we stop the scroll-event on different kind of events. I made an example for you without using jquery-ui. The scroll-timer is set to 2.5 sec so that you can stop it anytime before it reaches its target: JS-FIDDLE
function goTo(sectionID) {
var page = $("html, body");
page.on("scroll mousedown wheel DOMMouseScroll mousewheel keyup touchmove", function(){
page.stop();
});
page.animate({ scrollTop: $("#section" + sectionID).offset().top }, 2500, 'swing', function(){
page.off("scroll mousedown wheel DOMMouseScroll mousewheel keyup touchmove");
});
return false;
};
Can you try this :
$('.your-class-name-here').click(function(event) {
var id = $(this).attr("href");
var offset = 10;
var target = $(id).offset().top - offset;
$('html, body').animate({scrollTop:target}, 1000);
event.preventDefault();
});
});
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
I've got a simple piece of code like this
http://jsfiddle.net/QTa2c/
and all I want is, when user click on some of the last elements in list to show the content,
$('a.showMeThis').click(function() {
$(this).next('.content').slideToggle('fast', function() {
// there's go all the magic
});
});
and it goes outside the viewport (partly or completely) - scroll of the height of div, so he can see all of the content.
I was looking a lot for some logic for this, playing around with position().top, window.innerHeight and more, but it never goes in the way I want…
Hope you guys will help me, take care and have a nice day!
Use .animate() and .offset()
$('a.showMeThis').click(function () {
var $this = $(this);
$this.next('.content').slideToggle('fast', function () {
$('html,body').animate({
scrollTop: $this.offset().top
}, 'slow');
});
});
Fiddle Demo
Updated after OP's comment
Updated Fiddle Demo
$('a.showMeThis').click(function () {
var $this = $(this);
$this.next('.content').slideToggle('fast', function () {
if ($this.position()) {
if ($this.position().top + $this.height() > $(window).scrollTop() + (window.innerHeight || document.documentElement.clientHeight)) {
$('html,body').animate({
scrollTop: $this.position().top - (window.innerHeight || document.documentElement.clientHeight) + $this.height() + 15 + $this.next('.content').height()
}, 100);
}
}
});
});
With condition it looks like this: http://jsfiddle.net/QTa2c/1/
if ($(this).parent().offset().top + $(this).height() > window.innerHeight + $(window).scrollTop())
{
var a = $(this)
$('html,body').animate({scrollTop: $(a).parent().offset().top})
}
I think, this code is enough to understand the logic =)
UPD: note, that you should insert return false; into .click event to prevent jumping to # anchor.
Please check what i did yet http://jsfiddle.net/dUVmh/1/ .
About the animation i want to achieve is that:
When you first scroll down the page then window scroll to #green DIV. After that if you again scroll down window scroll to #yellow DIV & same at the time of scrollup (fom #yellow to #green).
About the issue:
You can see the animation it's stuck on #green DIV.
$(window).scroll(function(){
if($(this).scrollTop() > 0) {
$("html, body").animate({ scrollTop: $('#green').offset().top }, 1000);
}
else if($(this).scrollTop() > 1000) {
$("html, body").animate({ scrollTop: $('#yellow').offset().top }, 1000);
}
else{
$("html, body").animate({ scrollTop: $('#red').offset().top }, 1000);
}
});
I didn't have much experience in JS.
Thanks i advance :)
This was a fun problem to work on.
This solution places the divs into an array, and remembers the array index of the element that was last scrolled to. Once a scroll event is triggered it checks to see if the new scrollTop is above or below the current divs top offset and moves to the next or previous div in the array accordingly.
This solution allows you to have many divs. I tried to remove the flickering you get when you scroll to fast, but the only way to do that I believe would be to disable the scrollbars during animation.
http://jsfiddle.net/dUVmh/35/
$(function() {
var divs = [],
body = $('body, html'),
currentDiv = 0,
timeout;
$('div').each(function() {
divs.push($(this));
});
// we only need to capture the first scroll event triggered and then
// add another listener once we have done our animation
var scrollListen = function() {
$(window).one('scroll', function() {
doScroll($(this).scrollTop());
});
};
// Without the timeout, the scroll event would be triggered again too soon
var scrollEnd = function() {
clearTimeout(timeout);
timeout = setTimeout(function() {
scrollListen();
}, 10);
};
// checks if the scroll direction was up and down and animates
// the body scrollTop to the next or previous div
var doScroll = function(scrollTop) {
var direction = scrollTop - divs[currentDiv].offset().top;
if (direction > 0 && currentDiv + 1 < divs.length) {
nextDiv = currentDiv + 1;
} else if (currentDiv - 1 > -1) {
nextDiv = currentDiv - 1;
}
if (currentDiv === nextDiv) {
scrollEnd();
}
body.animate({
scrollTop: divs[nextDiv].offset().top
}, 1000, function() {
currentDiv = nextDiv;
scrollEnd();
});
};
scrollListen();
});
Edit: Firefox scrollTop required to be changed on html and not body. Also fixed a problem with firefox calling scrollListen more than once at a time.
The problem is that the $(window).scroll(function()) gets called over and over again when scrolling through the ScrollTop animation with jQuery.
Here is a possible solution that checks if it is currently scrolling or not and only executes the ScrollTop animation once.
http://jsfiddle.net/dUVmh/29/
Side note: It might be a good idea to check which direction the user is scrolling (up or down) and depending on that scroll to the next div to the top or to the down.
You can check that be saving the last scrollTop position and comparing it with the current one.
UPDATE: Here's a solution that takes the scroll direction into account: http://jsfiddle.net/dUVmh/36/