JQuery scroll to anchor acting odd - javascript

So i've got a script to scroll to an anchor on click. It doesnt seem to work on the "first" click going down. it will jump, rather than scroll. but after the first click, it jumps to the anchor and my menu appears, and then all the links (including the first one that jumped) work fine. im not sure what would cause this, and was wondering if anyone else would have an idea?
I have a JSFiddle, but it works fine there. only when i implement the same code into my site is when it happens.
Thanks
http://spo.comxa.com/
uploaded the files above for testing, same thing is happening.
http://jsfiddle.net/reeceheslop/b59fn43e/
$(document).ready(function () {
$('a[href^="#"]').on('click', function (e) {
e.preventDefault();
var target = this.hash,
$target = $(target);
$('html, body').stop().animate({
'scrollTop': $target.offset().top
}, 900, 'swing', function () {
window.location.hash = target;
});
});

Your click function seems to be nested inside of a scroll event listener, so I assume its not being called until something is scrolled. Try moving it to the outside along with the document ready function like this:
document.addEventListener('scroll', function (e) {
var newPos = (window.scrollY * -1) / 5
document.getElementById("header").style.backgroundPosition = "center " + newPos + "px";
var startY = 300;
$(window).scroll(function(){
checkY();
});
function checkY(){
if( $(window).scrollTop() > startY ){
$('.fixednav').slideDown();
}else{
$('.fixednav').slideUp();
}
}
checkY();
});
$(document).ready(function(){
$('a[href^="#"]').on('click',function (e) {
e.preventDefault();
var target = this.hash,
$target = $(target);
$('html, body').stop().animate({
'scrollTop': $target.offset().top
}, 900, 'swing', function () {
window.location.hash = target;
});
});
});

Related

JavaScript / JQuery - How to temporarily disable function after use?

I have a simple JS that would smoothly autoscroll to another div whenever mousewheel is moved up or down.
Here's the script:
$(document).bind('mousewheel', function(evt) {
var delta = evt.originalEvent.wheelDelta
if(delta < 0){
$('html, body').animate({
scrollTop: $("#content-wrapper").offset().top
}, 3000);
}
else {
$('html, body').animate({
scrollTop: $("#bgheader").offset().top
}, 3000);
}
});
My problem is that if i play for a few seconds with the mousewheel it would start scrolling here and there forever, since every move recorded is queued as additional script launch.
Is there any way to put some sort of 'cooldown' to the script? So that after using once it would become avaiable to use again in, let's say' 3 seconds? Or once the animation is finished?
You can unbind the wheel event listener, and then use jQuery's .animate() callback function to re attach the event listener after it is done, like so:
function scrollHandler (event) {
$(document).off("mousewheel.custom");
var delta = event.originalEvent.wheelDelta
if(delta < 0){
$('html, body').animate({
scrollTop: $("#content-wrapper").offset().top
}, 3000, function () {
// animation callback function
$(document).on("mousewheel.custom", scrollHandler);
}));
}
else {
$('html, body').animate({
scrollTop: $("#bgheader").offset().top
}, 3000, function () {
// animation callback function
$(document).on("mousewheel.custom", scrollHandler);
});
}
}
// namespace the event so we can easily .off() it
$(document).on('mousewheel.custom', scrollHandler);
I've used timeouts.
var maxPoll = 3000,
eventActive = false;
$(document).bind('mousewheel', function(evt) {
if(eventActive) {
return
} else {
setTimeout(maxPoll, function() { eventActive = True })
}
var delta = evt.originalEvent.wheelDelta
if(delta < 0){
$('html, body').animate({
scrollTop: $("#content-wrapper").offset().top
}, maxPoll);
}
else {
$('html, body').animate({
scrollTop: $("#bgheader").offset().top
}, maxPoll);
}
});
It's rough and it uses globals, but it basically turns off your event while the animation is running.

Smooth Scrolling to anchors. Different offsets. Media Queries. Excluding some anchors

Situation: I want to get smooth scrolling to anchor links, for every anchor link. Next i want to set an offset for specific anchor links (for example only the links of the navigation, but none of the anchor links on the site). And at last i want to add media queries.. so the offset position should only work at defined browser sizes (for example "max-width: 767px").
First problem: my smooth scrolling only works, if the other function (offset positioning) is disabled. Both together does not work. Any help?
Second problem: I don't know how to reduce "offset positioning" to "navigation" anchor links only.
// Smooth Scrolling
$(function () {
'use strict';
$('a[href*=#]').click(function () {
if (location.pathname.replace(/^\//, '') === this.pathname.replace(/^\//, '') && location.hostname === this.hostname) {
var target = $(this.hash);
target = target.length ? target : $('[name=' + this.hash.slice(1) + ']');
if (target.length) {
$('html,body').animate({
scrollTop: target.offset().top
}, 300);
return false;
}
}
});
});
// Offset Positioning
function offsetAnchor() {
'use strict';
if (location.hash.length !== 0) {
window.scrollTo(window.scrollX, window.scrollY - 0);
}
}
// Offset Positioning with media query
function offsetAnchor() {
'use strict';
if (matchMedia('only screen and (max-width: 767px)').matches) {
if (location.hash.length !== 0) {
window.scrollTo(window.scrollX, window.scrollY - 220);
}
}
}
// This will capture hash changes while on the page
$(window).on("hashchange", function () {
'use strict';
offsetAnchor();
});
I got the code by searching here and other sites, i didn't write it myself. I want to learn the basics of javascript and jquery soon. But it would be great to get help right now from you all. Thank you a lot!
boris
Ok, i found some other code here: Smooth scrolling when clicking an anchor link
And I've duplicated it once to add some media-query, offset and specific class (ul.nav a). I hope there are no problems - until now it works very fine for me. Hope this is a usefull solution! Even the code is smaller.
Only one "problem": The page scrolls two times. At first it scrolls to the anchor and a second time it scrolls 220px up again (the offset). It would be great if the page would only scroll one time to the offset position directly!
// Smooth Scrolling
var $root = $('html, body');
$('a').click(function () {
'use strict';
$root.animate({
scrollTop: $($.attr(this, 'href')).offset().top
}, 500);
return false;
});
// Smooth Scrolling with offset and media-query
var $root = $('html, body');
$('ul.nav a').click(function () {
'use strict';
if (matchMedia('only screen and (max-width: 767px)').matches) {
$root.animate({
scrollTop: $($.attr(this, 'href')).offset().top - 220
}, 500);
return false;
}
});
I got an optimization for my issue for smooth scrolling, finally. I think the media queries are much cleaner and understandable. Also the strange "scroll down and scroll some pixel up again"-effect is gone now.
// smooth scrolling
function screenMin768() {
'use strict';
var mq = window.matchMedia("(min-width: 768px)");
return mq.matches;
}
function screenMax767() {
'use strict';
var mq = window.matchMedia("(max-width: 767px)");
return mq.matches;
}
console.log(screenMin768() + " " + screenMax767());
if (screenMin768()) {
var $root = $('html, body');
$('a').click(function () {
'use strict';
$root.animate({
scrollTop: $($.attr(this, 'href')).offset().top - 55 // hier die variable aufrufen: "+ offset55"
}, 500);
return false;
});
}
// offset for normal a-tags, excluding mobile nav: ul.nav a
if (screenMax767()) {
var $root = $('html, body');
$('a:not(ul.nav a)').click(function () {
'use strict';
$root.animate({
scrollTop: $($.attr(this, 'href')).offset().top + 4
}, 500);
return false;
});
}
// offset for mobile nav: ul.nav a
if (screenMax767()) {
var $root = $('html, body');
$('ul.nav a').click(function () {
'use strict';
$root.animate({
scrollTop: $($.attr(this, 'href')).offset().top - 270
}, 500);
return false;
});
}
// offset correction for go-to-top button on mobile screen width
if (screenMax767()) {
var $root = $('html, body');
$('a.go-to-top').click(function () {
'use strict';
$root.animate({
scrollTop: $($.attr(this, 'href')).offset().top - 60
}, 500);
return false;
});
}
I am a designer only, so I got it by trial and error. I don't understand every line, for example "console.log ...". And I bet the code can be reduced much more.
So if anybody want to optimize / reduce the code, it would be great! :)

scrollTop() flickers when used in loop to fix an element at top of page

Click on the second div and see how it stutters.
Demo: http://jsfiddle.net/mirohristov/76xtt3hm/
$("body").on('click', '.mysection', function(){
var el = $(this);
if($(this).hasClass('active')){
url = $('.active .nectar-button').attr('href');
window.open(url, '_self')
}else{
$("html, body").animate({ scrollTop: el.offset().top+'px' }, 500,function(){
el.addClass('active');
var scroller = setInterval(function(){
$("html, body").scrollTop(el.offset().top);
}, 50); //if i change this to 14 or 1 it works here but in my real case there is more content and images in the divs and it's like 150 here - it's sluggish or flickers
$('.mysection').not(el).removeClass('active');
setTimeout(function(){window.clearInterval(scroller)}, 1000);
});
}
});
In the real project, I'm using divs as pages to display content. The selected div should aligned with top of page while the div above is being 'closed'.
I used a loop to re-set the scrollTop to that of the element position but in my real example it, even though the setTitmeout delay is 14 or 1, it acts like in the demo (at 50 delay).
I belive it's because there's more content and full-width, HD background images that go fullscreen in my actual project. It's as if the setTimeout is updated slower than the CSS animation.
How can I make it smooth? Is it even possible?
Try this (demo)
$('body').on('click', '.mysection', function () {
var scroller,
el = $(this),
html = $('html')[0],
body = $('body')[0];
if ($(this).hasClass('active')) {
url = $('.active .nectar-button').attr('href');
window.open(url, '_self')
} else {
el.one('transitionend', function (e) {
clearInterval(scroller);
});
$('html, body').animate({
scrollTop: el.offset().top + 'px'
}, 500, function () {
el.addClass('active');
scroller = setInterval(function () {
var top = el.offset().top;
html.scrollTop = top;
body.scrollTop = top;
}, 10);
$('.mysection').not(el).removeClass('active');
});
}
});

All the functions defined for onClick of button are getting called

I have below code in jsp and js. What's happening is irrespective of what button I am clicking both the javascript functions are getting called. I am not sure what am i missing here?
HTML:
<a type="button" id="scrollOffsetDiv" href="dashboard?offloglag=off&duration=${duration}#offset">Offset</a>
<a type="button" id="scrollMsgDiv" href="dashboard?offloglag=off&duration=${duration}#offset">Msg</a>
JS:
$(document).on("click","#scrollOffsetDiv", setTimeout(scrollOffsetDiv,3000));
function scrollOffsetDiv() {
var scrollTop = $(window).scrollTop(),
elementOffset = $('#offset').offset().top,
scrollDistance = (scrollTop-elementOffset);
alert("2222222222");
$('html, body').animate({
scrollTop: scrollDistance
}, 200);
}
$(document).on("click","#scrollMsgDiv", setTimeout(scrollMsgDiv,3000));
function scrollMsgDiv() {
var scrollTop = $(window).scrollTop(),
elementOffset = $('#msgsbytesinpersec').offset().top,
scrollDistance = (scrollTop-elementOffset);
alert("33333333");
$('html, body').animate({
scrollTop: scrollDistance
}, 200);
}
Adding jsfiddle link.
I was able to get it working with this jQuery code:
$("#scrollOffsetDiv").click(function(){ setTimeout(scrollOffsetDiv,3000); });
function scrollOffsetDiv() {
alert("2222222222");
}
$("#scrollMsgDiv").click(function() { setTimeout(scrollMsgDiv,3000) });
function scrollMsgDiv() {
alert("33333333");
}
Though I believe the main issue was simply needing to wrap your setTimeout function in a function(){}. Doing without that wrapper seems to only work with not parameterized calls to a function... if your calling a function with variables, wrap it in function(){}.
Anyone want to improve my vocabulary on the issue, please feel free. I've only learned this through observation.
An even more elegant way to write it might be:
$("#scrollOffsetDiv").click(function(){ setTimeout(function(){
var scrollTop = $(window).scrollTop(),
elementOffset = $('#offset').offset().top,
scrollDistance = (scrollTop-elementOffset);
alert("2222222222");
$('html, body').animate({
scrollTop: scrollDistance
}, 200);
},3000); });
$("#scrollMsgDiv").click(function() { setTimeout(function(){
var scrollTop = $(window).scrollTop(),
elementOffset = $('#msgsbytesinpersec').offset().top,
scrollDistance = (scrollTop-elementOffset);
alert("33333333");
$('html, body').animate({
scrollTop: scrollDistance
}, 200);
},3000) });

Getting some internal link animation to work

I have this script that opens a new page and scroll down to a id
var jump = function (e) {
if (e) {
e.preventDefault();
var target = $(this).attr("href");
} else {
var target = location.hash;
}
$('html,body').animate(
{
scrollTop: $(target).offset().top
}, 2000, function () {
location.hash = target;
});
}
$('html, body').hide();
$(document).ready(function () {
$('a[href^=#]').bind("click", jump);
if (location.hash) {
setTimeout(function () {
$('html, body').scrollTop(0).show();
jump();
}, 0);
} else {
$('html, body').show();
}
});
What I wanna do is, make it animate the scroll on the current page with internal links. How do I integrate that?
The easiest way would to just use links, like this.
It doesn't require jQuery or javascript, just some elements added to your HTML using IDs as href values
<a id='exampleTop' href='#exampleMiddle'>I'm an example! Click to go down</a>

Categories

Resources