Material Design Lite and jQuery, smooth scroll not working - javascript

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");
});
});

Related

JQuery positioning: I can scroll to the right place once but not twice

I recently started trying to mimic scrolling to a particular anchor in jQuery (tl;dr jumping to the anchor broke the outside of the page).
While the suggestions I've found on StackOverflow work for the first attempt to scroll down the page, I have found the second attempt isn't so successful.
I've probably been thinking about this too long, but I do have a Fiddle based on my woes:
http://jsfiddle.net/txns8bep/
var doThis = function() {
var parent = $('#crud');
var parentTop = $('#crud').offset().top;
var targetTop = $('#2').offset().top;
$(parent).animate({
scrollTop: targetTop// - parentTop
});
console.log('doThis() called. Went to '+targetTop+'-'+parentTop);
};
// works the first time
doThis();
// doesn't work the second time
setTimeout(doThis, 1000);
And the HTML (in part) is as follows:
<div id="crud" style="position:absolute;top:100px;bottom:0;overflow:scroll; border:1px solid red;">
<h1 id="1">Item #1</h1>Lorem ipsum....
<h1 id="2">Item #2</h1>Ab magnam...
<h1 id="3">Item #3</h1>Mollitia eius...
<!-- (h1[id=$]{Item #$}+lipsum)*10 -->
This problem isn't just about post-scrolling, though. ANY attempt to scroll to the relevant area is thwarted if the present offset top is greater than 0.
(Maybe it's just the caffeine talking, here, but I'm stumped.)
The answer was staring me in the face: scrollTop(). I modified the animation function as follows, and everything worked:
var newScrollTop = parent.scrollTop() + target.offset().top - parent.offset().top;
$(parent).animate({
scrollTop: newScrollTop
});
http://jsfiddle.net/txns8bep/1/

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

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.

jQuery - on window scroll run a function without any delay

I have an issue with a jquery function. You can see a working demo here - http://dev.sreejesh.in/menuissue/ . As you can see when the user scrolls down to the page, I have written a jQuery function(which will triger on scroll) to check scroll pixel. When the browser scrolls to a certain pixel(height of the sidemenu block), the Menu block will stay fixed & rest of the content scrolls as normal.
The functionality is working now, however the problem is menublocks makes a jumps when this function runs. I think this is because of the delay in running the function. Hope you guys have any nice trick to fix this.
I used an if/else function to check the scroll pixel, so when the scrolled pixel is greater than menublock height it will add a class "fixed" .
I use the following code.
HTML
<div id="globalwrapper">
<div id="menubar">
---- Menu List items-----
</div>
<div id="mainblock">
----Main content area----
</div>
</div>
jQuery
$(document).ready(function(){
$(window).scroll(function() {
adjustScroll();
});
});
function adjustScroll(){
var windowHeight = $(window).height();
var menublockHeight = $('#menubar').height();
var scrollValue = $(document).scrollTop();
var posValue = menublockHeight - windowHeight;
var menuStatus = $('#menubar').css('left');
$('#menubar').css('minHeight', windowHeight);
$('#menubar').css('height', menublockHeight);
console.log(menuStatus);
$(document).scroll(function() {
if(menuStatus == '0px') {
if(scrollValue > posValue){
$('#menubar').addClass('fixed');
$('#menubar').css('marginTop', -posValue);
}else {
$('#menubar').removeClass('fixed');
$('#menubar').css('marginTop', '0px');
}
}
});
}
I think only CSS can solve this issue, add this style:
#menubar{
position: fixed;
}
just test on Google Chrome,you can have a try.

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