jquery : how to jump to position without scrolling - javascript

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

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

Material Design Lite and jQuery, smooth scroll not working

I am unable to use .animate method of jQuery with Google's Material Design Lite(MDL). I have used MDL to make navigation bar, but smooth scrolling was not working.
Simple jQuery code is this:
$(function(){
$('a.smooth').click(function(){
console.log("SMOOTH BEGIN");
var speed = 1000;
var href= $(this).attr("href");
var target = $(href == "#" || href == "" ? 'html' : href);
var position = target.offset().top;
$("html, body").animate({scrollTop:position}, speed, "swing");
console.log("SMOOTH END");
});
});
And simple html code is this:
<!-- Navigation (this is included header) -->
<nav class="mdl-navigation">
<a class="mdl-navigation__link" href="">Home</a>
<a class="mdl-navigation__link smooth" href="#product">Product</a>
</nav>
<!--Main contents -->
<main class="mdl-layout__content">
<div id="product"><!—-Contents-—></div>
</main>
This code showed me the log, "SMOOTH BEGIN" and "SMOOTH END".
However, that link worked as ordinary link, not like smooth.
How can I get jQuery working with MDL? Maybe some conflicts are occurring, but console is not showing anything.
The reason you are not seeing anything happen is because you are scrolling on the body node. MDL handles the overflow within the mdl-layout__content, this is the element you should scroll on.
So this -
$("html, body").animate({scrollTop:position}, speed, "swing");
Now becomes-
$(".mdl-layout__content").animate({scrollTop:position}, speed, "swing");
Here's a codepen example -
http://codepen.io/mdlhut/pen/BNeoVa
Mitsuhiko Shimomura helped me in a different stack-overflow question. Instead of var position = target.offset().top; I used var position = target.get( 0 ).offsetTop - 130; if not the scroll would go to top and throw off the position, it did not look good. I had to add - 130 to the .offsetTop because the smooth scroll was going past my target id's in the html. Thank you for the help! See my app where I used this smoothscroll feature.
And remember to add smooth class to anchors in html like this
<a class="smooth" href="#scrollToId">Target</a>
<div id="scrollToId">Target</div>
$(function(){
$('a.smooth').click(function(){
console.log("SMOOTH BEGIN");
var speed = 1000;
var href= $(this).attr("href");
var target = $(href == "#" || href == "" ? 'html' : href);
var position = target.get( 0 ).offsetTop - 130;
$(".mdl-layout__content").animate({scrollTop:position}, speed, "swing");
console.log("SMOOTH END");
});
});

Scroll to section on click

I'm sure this is a pretty common question around here but after lots of research I can't seem to find an answer to my question.
So just a little warning; I'm really new into javascript and jQuery etc.
To the question! I'm trying to apply two images which you click on and it scrolls to the next or previous section.
So to get an overview of how it looks, here' a part of the HTML:
<div id="scrollbuttons">
<img id="prev" src="pics/prev.png"></img>
<img id="next" src="pics/next.png"></img>
</div>
And:
<div id="work">
<p class="maintext">blabla</p>
</div>
<div id="gallery">
<p class="maintext">blabla</p>
</div>
<div id="project">
<p class="maintext">blabla</p>
</div>
<div id="finish">
<p class="maintext">blabla</p>
</div>
Javascript:
var actual = "work";
$("#prev").on("click",function(e){
e.preventDefault();
var $prev = $("#"+actual).prev();
if($prev.length == 0){
return;
}
actual = $prev.attr("id");
$('html, body').animate({
scrollTop: $prev.offset().top
}, 1000);
});
$("#next").on("click",function(e){
e.preventDefault();
var $next = $("#"+actual).next();
if($next.length == 0){
return;
}
actual = $next.attr("id");
$('html, body').animate({
scrollTop: $next.offset().top
}, 1000);
});
So what I'm trying to create is when you click on "next", the page should smoothly and automatically scroll to firstly, "work", then to "gallery" etc.
And when you press "prev", the page should again smoothly and automatically scroll back to the previous point.
I have the latest jQuery version and I'd like to not install plugins if it's not absolutely needed.
So I hope this is enough info to get some help, I'd really appreciate it since I'm really new to JS.
Thanks in advance
/Emil Nilsson
You best use a plugin as they already invented the wheel: jQuery ScrollTo
If you don't want to use the plugin, you can still learn from it by checking the code of the non-minified version.
I think you should introduce an indicator like a classname to determine the current active section and move that class together with scrolling when you click prev or next.
$('#scrollbuttons a').click(function (e) {
e.preventDefault();
var el, pos, active = $('#sectionContainer .active');
if ($(this).is('#prev')) {
el = active.prev();
} else {
el = active.next();
}
if (el.length) {
pos = el.offset().top;
$('html, body').animate({
scrollTop: pos
}, 1000);
el.addClass('active').siblings().removeClass('active');
}
});
See the demo.
If you want to integrate this with scroll() event, you also need to move that indicator when the scrollTop reaches a certain section:
$(window).scroll(function(){
var winTop = $(this).scrollTop();
$('#sectionContainer div').each(function(){
var elTop = $(this).offset().top,
elHeight = $(this).height();
if(winTop >= elTop && winTop < elTop + elHeight){
$(this).addClass('active').siblings().removeClass('active');
}
});
});
With scrollbar demo.

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!

hashchange prevents scrolling to targeted div

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/

Categories

Resources