hashchange prevents scrolling to targeted div - javascript

I have an accordion element, and I need to have different panes expand on hashchange. The code I made, expands it but it doesn't scroll the the targeted div, and page never ends loading.
function hashChange() {
if (window.location.hash === '#senior-backend') {
$('#senior-backend, #backend-developer, #senior-frontend, #frontend, #dev-ops').hide(50);
$('#senior-backend').show(50);
$('#job-posts').removeClass().addClass('beige-bg');
$('#job-posts-top').removeClass().addClass('beige-spikes');
}
}
window.onhashchange = hashChange;
Could you please point out what am I doing wrong.
Thanks

You need to scroll the site using animate once you detect a change in the hash, for example:
var dest = $('#yourSelector').position();
var dtop = dest.top;
$('html, body').animate({
scrollTop: dtop
});
Living demo: http://jsfiddle.net/LZbK8/

Related

Scrolling to anchors unpredictable

I am trying to build a simple vertical timeline. You can click up or down to scroll it little by little but I also wanted to have it jump, smooth scroll, to anchors. This somewhat works but the behavior is unpredictable.
This isn't usually difficult but something new for me is that the scrolling behavior is inside a div so the whole page shouldn't be moving.
You can try it in the fiddle. Clicking random buttons will sometimes bring you to the right spot, other times it will just scroll to a random place.
JSFiddle
Here is the basic Jquery.
var step = 280;
var scrolling = false;
$(".scrollUp").bind("click", function (event) {
event.preventDefault();
$("#timeline").animate({
scrollTop: "-=" + step + "px"
});
})
$(".scrollDown").bind("click", function (event) {
event.preventDefault();
$("#timeline").animate({
scrollTop: "+=" + step + "px"
});
})
$('.timelineButton').click(function () {
$('#timeline').animate({
scrollTop: $($(this).attr('href')).offset().top
}, 2000);
return false;
});
A few things need fixing :
Use .position().top (relative to offset parent) instead of .offset().top (relative to document)
Specify the offset parent by styling the #timeline container with position: relative
Because .position() returns dynamically calculated values, .position().top will be the value-you-want minus the current-scrollTop. Therefore you need to add the current-scrollTop back on.
CSS
#timeline {
...
position: relative;
}
Javascript
$('.timelineButton').click(function (event) {
event.preventDefault();
$('#timeline').animate({
scrollTop: $($(this).attr('href')).position().top + $('#timeline').scrollTop()
}, 2000);
});
Demo
Add Ids to each div & use that ID like href="#ID". This will scroll window to that particular section ID given in href
Check this
$('.timelineButton').click(function () {
if($('#timeline').is(':animated')){}else{
$('#timeline').animate({
scrollTop: $($(this).attr('href')).offset().top
}, 2000);
return false;
}
});
.is(':animated') will be tell you if the element is animating, if not, animate it.
It prevent the unpredictable jumps.
EDIT
Best way to prevent this is: .stop().animate
$('.timelineButton').click(function () {
$('#timeline').stop().animate({
scrollTop: $($(this).attr('href')).offset().top
}, 2000);
return false;
});
EDIT V2
Check this Fiddle: https://jsfiddle.net/a489mweh/3/
I have to put the position offset of each elements in an array, becouse every animate in timeline change the offset.top of each element.Check the data-arr="0" over each button, to tell the array what position of the element have to retrieve.Tell me if works.
Cheers

jquery : how to jump to position without scrolling

I wrote the following function, which scrols to some anchor position, when href is clicked:
$("a").click(function() {
href="#myAnchor";
var fromTop = 95;
if(href.indexOf("#") == 0) {
var $target = $(href);
if($target.length) {
$('html, body').animate({ scrollTop: $target.offset().top - fromTop });
return false;
}
}
};
return false;});
How to change this function, sothat I jump to my anchor without "scrolling". when the href is clicked, it should be jumbed to myanchor position directly.
This is standard feature of HTML called 'bookmarks', no JS required. First place your bookmark where you would like the browser to scroll to:
<a name="my-bookmark"></a>
Then place your link to it where required:
Go to bookmark
HTML5 also allows you to specify the bookmark by id of the element:
<div id="foo">Foo</div>
<!-- in another part of the page, far far away -->
Go to foo
Update
If you need to allow padding at the top of the page then you could use the <a name="x"></a> method and place them at the required distance above the target, although that could become difficult to maintain.
You could use this JS in that scenario:
$("a.bookmark").click(function(e) {
e.preventDefault();
var href = $(this).attr(href);
var fromTop = $('#fixed-header').height();
$(window).scrollTop($(href).offset().top - fromTop)
});
By default, animate() has speed set to "400ms". You should put it at 0 :
$('html, body').animate({ scrollTop: $target.offset().top - fromTop }, 0);
EDIT: Or use scrollTop() as #Rory McCrossan explains
instead of animate use .scrollTop() this way:
$(document).scrollTop($target.offset().top - fromTop);
Here's a simple way without using any script:
assign href the id of the div to where you want to jump to
<a href='#jumpto'>Jump</a>
<div id='jumpto'></div>
without jQuery, only HTML
go to aaaaa | go to bbb
<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.
<a name="aaa">aaa</a>
<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.
<a name="bbb">bbb</a>
<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.
EXAMPLE

Modifying this scrolling nav menu script?

I am a noob and for a school project I was trying to create a single page site that had a static nav menu at the top that always stayed there and I wanted it to do an animated scroll effect when you click it's link. Someone here made this for me and it works perfect.
However, you notice it says .top - 98 and that is because my nav is 98px tall so that it doesn't cut off the section it's jumping to.
Now that I am getting into media queries, I may increase the height of that nav at certain breaks. So I am wondering, is it possible to change this from 98 to some sort of [nav current height] variable? So that it will work regardless of what the height of my nav is?
Thanks in advance!!
$(document).ready(function() {
$("nav a").on('click', function() {
var link = $(this).attr('href');
$('html,body').animate({
scrollTop: ($(link).offset().top - 98)
}, 'slow');
return false;
});
});
how about
$('html,body').animate({scrollTop: ($(link).offset().top - $('nav').height())},'slow');
Yes you can do that
scrollBarFunc = function(){
var myNavHeight = $("#myselectorId").height(); //just put here your id or class
$("nav a").on('click',function(){
var link = $(this).attr('href');
$('html,body').animate({scrollTop: ($(link).offset().top - myNavHeight)},'slow');
return false;
});
}
$(document).ready(function(){
scrollBarFunc();
});
$(window).resize(function(){
scrollBarFunc(); //recall function to work when you resize
});

Smooth scroll + offset on function goToNext

I am wanting to add an offset from the top and smooth scroll to the following function,
The functionality is on one button thats fixed and follows the user down the page. This button has to be able to scroll through numerous anchors and then go back to the first one, with an offset ideally of 105px from the top. trawled the net for hours for help and dont have the jquery know how myself to fix this, any help??
Similar example here - http://www.google.com/nexus/7/ (button in bottom right)
<script>
var max = 6;
function goToNext() {
var hash = String(document.location.hash);
if (hash && hash.indexOf(/anchor/)) {
var newh = Number(hash.replace("#anchor",""));
(newh > max-1) ? newh = 0 : void(null);
document.location.hash = "#anchor" + String(newh+1);
} else {
document.location.hash = "#anchor1";
}
}
</script>
<div id="anchor1"></div>
<div id="anchor2"></div>
<div id="anchor3"></div>
<div id="anchor4"></div>
<div id="anchor5"></div>
<div id="anchor6"></div>
You can make it scroll smoothly to the element using animate({scrollTop:value},delay).
$('document').ready(function () {
//on DOM ready change location.hash to 'anchor1'
window.location.hash = 'anchor1';
//GO TO NEXT click event:
$('a').click(function (e) {
//preventing the default <a> click (href="#")
e.preventDefault();
//get the current hash to determine the current <div> id
var hash = window.location.hash,
//find the (next) immediate following sibling of the current <div>
$next = $(hash).next('div');
//check if this next <div> sibling exist
if ($next.length) {
var id = $next.attr('id'),
nextOffsetTop = $next.offset().top;
//animate scrolling and set the new hash
$('body, html').animate({scrollTop: nextOffsetTop}, 'slow');
window.location.hash = id;
}else{
//else if the next <div> sibling does not exist move to the first anchor
var first = '#anchor1';
$('body, html').animate({scrollTop: $(first).offset().top},'slow');
window.location.hash = first;
}
});
})
See this jsfiddle.
Then comes the flickering. Actually it does not flicker but somewhat jerky, if you look closely into the code above. I am setting the animate(scrollTop) first, then changing the hash window.location.hash = id. Now when the animate starts scrolling and suddenly we are changing the hash it tends to jump directly to the next <div> (this is the default haschange event) but pulled back by the animate() and that causes the scrolling to be jerky.
We cannot just stop the default propagation of the haschange event, there may be a solution to do that but cannot guarantee that it would work on all browsers, each browser has different behaviour when it comes to the haschange event. But thanks to #Andy E solution on that SO post you've provided, we don't need to stop the haschange propagation. We can just simply change the hash first, reset it to last scrollTop() position then animate scrolling at will!
//get the current scrollTop value
var st = $(window).scrollTop();
//change the hash
window.location.hash = id;
//reset the scrollTop
$(window).scrollTop(st);
//animate scrolling
$('body, html').animate({scrollTop: nextOffsetTop}, 'slow');
Check this updated jsfiddle.
Now let's talk about HTML5 History API. The reason I didn't introduced this at first because it is implemented differently across HTML5 (especially IE) browsers and has no fallback for HTML4 browsers, making this method somehow inconsistent. But you can get this done properly using a plugin I guess.
Here's how you can do it using history.pushState():
if ($next.length) {
var id = $next.attr('id'),
nextOffsetTop = $next.offset().top;
history.pushState({state:id}, id, '#'+id);
$('body, html').animate({scrollTop: nextOffsetTop - 105}, 'slow');
}
See this jsfiddle.
That's it. Cheers!

Stop DIV scrolling once it reaches the footer (another DIV)

I have a "back to top" button that appears when the user scrolls down the page.
With some help I have managed to implement these functions in the code below:
fade in at certain point after scrolling down, animated scroll back to top and animated scrolling to all href="#" links of the page.
$('a[href^="#"]').on('click',function (e) {
e.preventDefault();
var target = this.hash,
$target = $(target);
$('html, body').stop().animate({
'scrollTop': $target.offset().top
}, 800, 'swing', function () {
window.location.hash = target;
});
});
var $win = $(window);
$win.scroll(function () {
if ($win.scrollTop() > 300) {
b.fadeIn();
console.log("fadding in")
}
else {
b.fadeOut();
}
});
});
Here is a working exsample: http://jsfiddle.net/q8DUC/8/
My problem is that the button scrolls into the footer of the page...
Basically the "back to top" should stop 30px above the "footer" DIV.
But I can't find a way to accomplish that. I've looked around but haven't found anything that worked with the existing code.
Thanks for any help or suggestions!
UPDATE:
Got a bit further: http://jsfiddle.net/q8DUC/20/
Just don't know how I can avoid the jumping of the button!
Is there a way to stick the button to the bottom instead the top:0???
As always THANKS for every suggestion or help!
I think you could get the location of the footer and add it to your conditional, which checks if the button should be displayed:
// dynamically get the position of the footer
var FOOTER_POSITION = someNumber;
// i THINK something like var FOOTER_POSITION = $('#T4').position().top; could work
if (300 < $win.scrollTop() && $win.scrollTop() < FOOTER_POSITION) {
Sorry, I read your question wrong, since you are using fixed positioning for your button you could implement something like:
get the height of the footer + 30px
Get a location of the footer in relation to the document, based on your fiddle ~2000px (FOOTER_START)
if the location of the top of the window is > 300 AND it is greater than (FOOTER_START) change #back-top bottom property to height of your footer

Categories

Resources