I have noticed an odd behavior while using jquery's scrollTop in IE 9, 10 & 11. When the function is triggered, IE resets the page scroll position to 0, the very top, then it animates down to the correct section. I am looking for a way to have the scroll behavior match that found in other browsers where it scrolls from the current position. Here is my relevant code:
First, I bind the click event to my element:
$("body").on("click", ".marker", function() {
window.requestAnimationFrame(function() {
theAutoScrollingFunctions.scrollToTarget("city", 5000);
});
});
Then my scrolling function:
$("html,body").animate({ scrollTop: $(document).height()}, 500, function() {
// Callback stuff
});
The scrolling technically works but in IE the page is reset to the top and then scrolls. I have tried placing return false; values throughout the process but with no luck.
Has anybody else seen this issue?
I use the same animate function when doing scroll-to sections on the sites I build. When testing in IE 8+ it works perfectly. Perhaps the $(document).height() is the part that makes the reset happen at the top?
This is how I like to do it:
<ul id="section-links">
<li>Scroll to section1<li>
<li>Scroll to section2<li>
</ul>
<section id="section1">
<h1>This is the first section</h1>
</section>
<section id="section2">
<h1>Another example section</h2>
</section>
<style>
section{display:block;width:100%;min-height:300px;}
</style>
<script>
jQuery(document).ready(function($){
$('#section-links a').click(function(){
var section = $(this).attr('href');
$('html, body').animate({scrollTop:$(section).offset().top - 10}, 'slow');
});
});
</script>
As you can see, I like to add some space above the scrolled-to section, so the title and whatnot is not jammed up against the viewport.
I have not seen the bug you describe using this method.
Best of luck
The issue seemed to be with my jQuery selector.
$("html,body").animate....
Changed to
$("html").animate....
This looks to have solved the issue in IE9+ and kept consistent behavior across the other browsers I have tested.
Related
I need to scroll the page on load to a certain position on the page in an animated manner. And it works fine (using jQuery's animate):
$(document).ready(function () {
$('html, body').animate({
scrollTop: $('#today').offset().top - 50
}, 800, "linear");
});
However, one thing that it is not is smooth. Particularly on a mobile device it feels very jerky.
I've seen some CSS animations (using transition and transform) that are very smooth but can't figure out how to apply it to page scrolling. Is it possible to do what I want using CSS?
Try setting the following css:
<style type="text/css">
html {
scroll-behavior: smooth !important;
}
</style>
You could also try using vanilla JavaScript instead of jQuery:
function showIt(el_id) {
var el = document.getElementById(el_id);
el.scrollIntoView(true, {behavior: "smooth"});
}
showIt('today')
Also consider adding an itermediary element in the middle of the page, example:
<div id="middle" style="display: none;"></div>
function showIt(el_id) {
var middle_el = document.getElementById('middle');
var el = document.getElementById(el_id);
middle_el.scrollIntoView(true, {behavior: "instant"}); // Go to middle directly and then scroll slowly to #today.
el.scrollIntoView(true, {behavior: "smooth"});
}
showIt('today')
More info on scrollIntoView: https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView
Also you might be interest in: Scrolling slow on mobile/ios when using overflow:Scroll if you are on iOS
Try using easeOutCubic or another easing function (choose one here):
$(document).ready(function () {
$('html, body').animate({
scrollTop: $('#today').offset().top - 50
}, 800, "easeOutCubic");
});
The best solution for cross-browser/cross-device decent smooth scrollTop I found is using velocity.js. It's faster than jQuery's animate, quite light and supports multiple syntaxes, one of them being the one used by jQuery.animate(), so all you need to do is to replace .animate() with .velocity() (and loading the thing, of course).
I know there might be other solutions out there, but this one has been solid for years, they are always keeping it up to date, I'd say it's a keeper in any serious frontend web developer's tools. You'll find some very fancy names on velocity's libscore page. And no, I'm not affiliated. I'm just thankful for being able to use it for free.
I am trying to use a smooth scroll and adopted an example I found online. Here is a fiddle with my code
https://jsfiddle.net/4DcNH/144/
I have special conditions set to html and body (basically to offset the page context by 50px from the top to avoid the navbar). Therefore the smooth scroll does not work. Does anybody know a solution to this?
thanks
carl
$(document).ready(function() {
$('a[rel="relativeanchor"]').click(function(){
$('html, body').animate({
scrollTop: $( $.attr(this, 'href') ).offset().top
}, 2000);
return false;
});
});
Is this what you're after?
$(document).ready(function () {
if(!/chrom(e|ium)/.test(navigator.userAgent.toLowerCase())){
$('html').css({'overflow-x':'auto','overflow-y':'hidden'});
}
$('a[rel="relativeanchor"]').click(function () {
var $el = $($(this).attr('href'));
$('html, body').stop().animate({
scrollTop: $el.prop('offsetTop')
}, 2000);
return false;
});
});
JSFiddle
Updates were needed in the CSS. The html overflows were removed for chrome, because otherwise, this would not work in Chrome. However, the overflows are needed for Firefox, so they are done by setting it dynamically in the JavaScript (set if not chrome).
If you want to maintain an offset, subtract it from the calculated offset. Given the above, $el.prop('offsetTop') - 50 adds 50px above.
The issue appears to be related to differences in how Chrome scrolls the <body> with height:100%. A discussion of the issue is here: Body set to overflow-y:hidden but page is still scrollable in Chrome
A workable solution is to wrap the scrolling content in <div class="content"> and disable scrolling on <body>.
Here's a JSFiddle to demonstrate the updated behavior: https://jsfiddle.net/f1zv1c5k/5/
To get the scroll to stop at the appropriate point, you need to subtract the vertical offset applied to the <html> tag (using $el.prop('offsetTop') recommended by #vol7ron) when scrolling. Your smooth scroll function would look like this:
$('a[rel="relativeanchor"]').click(function(){
var $el = $($(this).attr('href'));
$('.content').animate({
scrollTop: $el.prop('offsetTop')
}, 2000);
return false;
});
Forgive me if this has been asked, but I've been searching all day on here and have not seen any question relating to my specific problem.
I'm building a one page parallax-style website with a navigation bar utilizing a fixed position to allow users to quickly jump to different sections of the page.
Currently I'm trying to implement the scrollTo jQuery plugin (flesler/jquery.scrollTo - Github) to give a nice smooth animated scroll.
This is the 5th or 6th different jQuery method I've implemented to make this effect work with no success. The scrollTo method seems to be the closest to working, but it still won't work.
It does not work at all on Chrome 42.0.2311.90
It does not work at all on Firefox 37.0.2
It does work on Safari 5.1.10, but I haven't been able to check on the newest version of Safari. Also the site doesn't render right on Safari 5.1.10 yet. I also have not had access to a computer with IE.
The test site is located at http://revolt-designs.com/parallax/
Here is how I'm calling the script:
$(document).ready(function(){
$('#nav-links li a').click(function() {
$.scrollTo($(this).attr('href'), {duration: 3000});
});
});
And the links are formatted this way:
<div id="nav">
<ul id="nav-links">
<li>About</li>
<li>News</li>
<li>Events</li>
<li>Contact</li>
</ul>
</div>
For the sake of simplicity, the anchors are pointing to divs located on the page, ie:
<!-- GROUP 2 -->
<div id="group2" class="parallax__group">
<div class="parallax__layer parallax__layer--base">
Lorem Ipsum
</div>
</div><!-- end GROUP 2 -->
Hopefully someone will catch something small and easy that I'm missing. Thanks. To be clear, I'm not asking for an alternative to the script I'm using. I'm asking for help finding the underlying issue that's preventing any smooth scrolling scripts from working on my site.
Change your code to scroll on the .parallax element:
$(document).ready(function() {
$('#nav-links li a').click(function() {
$('.parallax').scrollTo($(this).attr('href'), {duration: 3000});
});
});
Here is a fiddle (Used the HTML from your webpage)
For the sake of browser compatibility, you could consider changing height: 100vh; in your css to perhaps use .height() instead:
$(document).ready(function() {
height = $(window).height();
$('.parallax').css('height',height);
$('#nav-links li a').click(function() {
$('.parallax').scrollTo($(this).attr('href'), {duration: 3000});
});
});
This snippet required jquery and jquery UI, you can remove the easing part at the end if you do not want to include jquery UI
$(document).ready(function(){
$('#nav ul li a').on('click', function(e) {
e.preventDefault();
var target = $(this).attr('href');
//changing the value of offsetValue will help account for fixed headers or whatever.
//EDIT: used data-offset to allow for multiple offsets defualt is 0.
offsetValue = $(this).data('offset') | 0;
$('html, body').animate({
scrollTop: $(target).offset().top-offsetValue
},
{
duration: 2000,
easing: "easeOutQuint"
});
//number at the end here changes the speed, slower = higher
});
});
I am using the following javascript to pull in a 'back to top' button when scrolling down.
This works great on Firefox - but doesn't work on Chrome/Safari.
jQuery(document).ready(function(){
jQuery("#totop").hide();
jQuery(window).scroll(function(){
if (jQuery(this).scrollTop() > 100) {
jQuery('#totop').fadeIn();
} else {
jQuery('#totop').fadeOut();
}
});
jQuery('#totop').click(function(){
jQuery("html, body").animate({ scrollTop: 0 }, 660, 'easeInOutExpo');
return false;
});
});
Demo site http://demov3.joostrap.com
I have tried using noConflict.
As I've mentioned in the comments, there's a known issue with Google Chrome and some other WebKit browsers regarding fixed position and z-index.
Checking your page source, I would recommend the following changes:
<-- Set the body element z-index value to 0 (inline or
on the CSS stylesheet) -->
<body class="com_content view-featured layout- task- frontpage itemid-101 no-rtl" style="z-index: 0;">
<div class="body-wrapper">
...
</div>
<-- Stick the link as the last element within the body element, and change
its z-index value to 9999 (on the CSS stylesheet) -->
</body>
Basically I have an unordered list acting as my navigation on a one page website sorted by sections. These sections or panels are full width and height of the browser window.
In the first panel, this list is vertical but when the user scrolls down the page to section two (i.e. the second panel from the top of the browser window) I'd like to change the style of it so that it fixes to the top of the browser window and becomes a horizontal nav instead of a vertical one. I don't want to duplicate the list if possible.
I'm not great at jQuery and don't really know where to start. Any help would be great.
This is my current code that gets the width and height of the browser window and displays a full screen div:
function fitElements(){
var height=$(window).height();
var width=$(window).width();
$('.panel').css('height',height);
$('.panel').css('width',width)
};
Here's a very simple example:
DEMO
html:
<ul id="nav">
<li>One</li>
<li>Two</li>
<li>Three</li>
</ul>
<div id="divOne" class="panel">
</div>
<div id="divTwo" class="panel">
</div>
<div id="divThree" class="panel">
</div>
css:
#nav {
position:fixed;
top:0;
left:10px;
}
#nav.horizontal li {
float:left;
}
#divOne {
background-color:#cef;
}
#divTwo{
background-color:#efc;
}
#divThree{
background-color:#fce;
}
js/jQuery:
$("div.panel").css({
height: $(window).height(),
width: $(window).width()
});
$(window).scroll(function() {
($("#divTwo").offset().top <= window.pageYOffset) ? $("#nav").addClass("horizontal") : $("#nav").removeClass("horizontal");
});
$("#linkOne").click(function(e){
$('html, body').animate({
scrollTop: $("#divOne").offset().top
});
$("#nav").removeClass("horizontal");
e.preventDefault();
});
$("#linkTwo").click(function(e){
$('html, body').animate({
scrollTop: $("#divTwo").offset().top
});
$("#nav").addClass("horizontal");
e.preventDefault();
});
$("#linkThree").click(function(e){
$('html, body').animate({
scrollTop: $("#divThree").offset().top
});
$("#nav").addClass("horizontal");
e.preventDefault();
});
Okay, providing I understood you correctly (see my comment looking for clarification), your goal is to make sure that your navigation pane is visible to your site visitors even when they scroll down the page. I would caution you against changing the nav bar to show horizontally after reaching a certain point on the page only because it will look pretty choppy, especially in slower browsers, unless (and sometimes even if) you provide a lot more code (complex for a novice) to smooth out the transition.
What I suggest is that you take a look at this question from a few days ago. I created a demo for the effect that he was looking for, which is very similar to what you are looking for, and hosted it on my development site. Take a look and if it's something that you like and if it is and you have trouble implementing it let me know and I'll be more than happy to help you.