scroll automatically to target with jQuery in iOS running too far - javascript

I have an anchor that when click I have the following jQuery firing:
$(document).on('pageinit', function (event, ui) {
var page = $(event.target);
page.find('a.course_name').on('vclick', function() {
page.stop().animate({ scrollTop : $(this).offset().top }, 400);
}
}
What I am finding on the iPhone 5 running iOS 6 is that the animation of the scroll doesn't stop at the top of the anchor as I would like. It sometimes stops short, or runs past dependant on what I have scrolled to in the page previously.
I am also using jQuery Mobile, but essentially the page variable is the scrollable area.

I don't know your HTML markup or your CSS styles, but depending on it, position can return a different result than offset.
Try it with position() instead:
page.stop().animate({ scrollTop : $(this).position().top }, 400);

Related

Is there anyway to prevent page jumps (from loading images) while scrolling to a div?

I use the following code on page load to smoothly scroll to a div
$(document).ready(function() {
$('html,body').delay(50).animate({scrollTop:jQuery('#3342').position().top-10}, 'slow');
});
It works wonderfully to smoothly scroll the page to a predefined div id (in this case div id=3342, but the actual div ID changes depending on what button the user clicks).
The problem is that if there are any images in the pages above div 3342, then after the scroll finishes, the page jumps and the entire positioning scroll is for nothing, as that content is no longer on screen.
This is on mobile safari btw. I know Google chrome has recently introduced Scroll anchoring, and I believe this is the functionality i'm trying to reproduce somehow.
Just FYI, I have no way of knowing the sizes of images or the ratio of the image sizes ahead of time. They are random images from around the web
Thanks!
EDIT: I don't want to change to window/load event as that means I would have to wait for all the images to load first, which would delay the scroll event massively on some pages
EDIT: The image URLs are all on the source page, no ajax loading of pages after the fact
Repeat until complete:
$(document).ready(function() {
var div = jQuery('#3342');
var complete = false;
function adjust () {
if (!complete) {
$('html,body').delay(50).animate({scrollTop:div.position().top-10}, 'slow', adjust);
} else {
$('html,body').delay(50).animate({scrollTop:div.position().top-10}, 'slow');
}
}
adjust();
$(window).on('load', function () {
complete = true;
});
});

Prevent window scroll below fold until button click

I have a situation where I need the page to not be scrollable past a certain point (I have the hero set to 100vh and the user should not be able to scroll at all) and then upon click of a button the scroll prevention is disabled and the user is then automatically smooth scrolled down to an anchor link directly below (basically scroll down 100vh or the full window height). I need a smooth scrolling animation instead of just a quick jump.
I've tried playing around with variations of the following code with no luck. So far it is really buggy and jumps around and when you reload the page the body overflow is set to hidden but the window position is not always at the top of the screen so you still see some of the below the fold content but still cant scroll.
function() {
function smoothScroll(){
windowHeight = $('window').height();
$('html, body').stop.animate({scrollTop: windowHeight}, slow);
}
$('.bottom-nav').on('click', '.fold-trigger', function(event) {
$('.home').css('overflow', 'visible');
setTimeout(smoothScroll(), 1000);
});
};
Fiddle is here: https://jsfiddle.net/njpatten/yxkvnymu/1/
Fixed Code
function smoothScroll(){
windowHeight = $(window).height();
$('html, body').stop().animate({scrollTop: windowHeight}, "slow");
}
$('.bottom-nav').on('click', '.fold-trigger', function(event) {
$('.home').css('overflow', 'visible');
setTimeout(smoothScroll(), 1000);
});
Fixed fiddle: https://jsfiddle.net/yxkvnymu/2/
Explanation
You are trying to get the window height by doing $('window').height() which is searching for a 'window' DOM element which doesn't exist. You want to use $(window).height() (note the omission of quotes surrounding window) because window is not a DOM node, it is an object.
In addition, you are using $('html, body').stop.animate({scrollTop: windowHeight}, slow); which has multiple errors. .stop is invalid because the stop property on the NodeList that is returned from $('html, body') is a function that you want to call. You should be using $('html, body').stop().
Also, the animate portion is referencing a variable slow. jQuery's animate function takes "slow" as a string, so that line should be written as such:
.animate({scrollTop: windowHeight}, "slow");
Note the inclusion of quotes on that because we want to pass a string value of "slow" to jQuery's animate function, instead of a variable slow.
Lastly, you are surrounding all of your code in an anonymous function, which seems unnecessary.

jQuery - scroll or jump to top

The context: I have a one page web app. So there's lots of div's being hidden at any one time (I'm not sure if this matters). What I am finding is that when a user is finished with one page (Page X), then they click back (to Page Y) - if they return back to Page X then the position is the same as when they left the page. The back button is at the bottom, so that's where the user ends up again.
What I want, is when they return to Page X for them to be at the top of the page so they can start again. Whether it scrolls back or just jumps back - either way is fine.
I've tried all of the following with no success:
// Scroll to top
setTimeout(function(){
alert('scroll');
$('html, body').animate({scrollTop : 0}, 2000);
}, 2000);
Adding a div with the id top-anchor at the top and using:
$('html, body').animate({
scrollTop: $("#top-anchor").offset().top
}, 2000);
Having a and using an anchor, with the code below (it only works once though, after that as the hash is already in the URL it no longer works I suppose):
document.hash = '#top-anchor';
Also tried:
window.scrollTo(0, 0);
No luck.
Any alternative ideas are much appreciated.
You can achieve something like that: DEMO : https://jsfiddle.net/yeyene/bpwtLg1w/1/
Not sure how your content divs are shown and hidden, but just get the idea of adding scroll to top of page div part.
Add scroll event on Back button click event, since you already known which page to go, you can scroll to this page's top, by using...
$(element).position().top
JQUERY
$(document).ready(function () {
$('input[type=button]').on('click', function(){
getPageID = $(this).attr('id');
$('.page').hide(0);
$('div#'+getPageID).show(0);
$('html,body').animate({
scrollTop: $('div#'+getPageID).position().top - 10
}, 500);
});
});

IOS - after jquery animate scrollTop, it prevents divs being clicakble until user scrolls manually

$('.topNavigationBtn').on('click',function (e) {
var target = $(this).attr('targetId');
$("body").animate({ scrollTop: $(target).offset().top }, 1000);
})
Please note this isn't on all IOS devices, but on some, after the first animation, until the user manually scrolls the page the topNavigationBtn's are no longer clickable. Any ideas why this would be would much appreciated.
The answer is to hack.
If you add a div at the bottom of the page, that you change the height of on animate complete, this then lets IOS update the scrollTop, without the user needing to scroll themselves.
J

JQuery UI Tabs Causing Screen to "Jump"

I'm using the latest version of the jQuery UI tabs. I have tabs positioned toward the bottom of the page.
Every time I click a tab, the screen jumps toward the top.
How can I prevent this from happening?
Please see this example:
http://5bosses.com/examples/tabs/sample_tabs.html
If you're animating your tab transitions (ie. .tabs({ fx: { opacity: 'toggle' } });), then here's what's happening:
In most cases, the jumping isn't caused by the browser following the '#' link. The page jumps because at the midpoint of the animation between the two tab panes, both tab panes are fully transparent and hidden (as in display: none), so the effective height of the whole tabbed section becomes momentarily zero.
And if a zero-height tabbed section causes the page to be shorter, then the page will appear to jump up to compensate, when in reality it's simply resizing to fit the (momentarily) shorter content. Makes sense?
The best way to fix this is to set a fixed height for the tabbed section. If this is undesirable (because your tab content varies in height), then use this instead:
jQuery('#tabs').tabs({
fx: { opacity: 'toggle' },
select: function(event, ui) {
jQuery(this).css('height', jQuery(this).height());
jQuery(this).css('overflow', 'hidden');
},
show: function(event, ui) {
jQuery(this).css('height', 'auto');
jQuery(this).css('overflow', 'visible');
}
});
It will set the computed height of the pane before the tab transition. Once the new tab has appeared, the height is set back to 'auto'. Overflow is set to 'hidden' to prevent content from breaking out of the pane when going from a short tab to a taller one.
This is what worked for me. Hope this helps.
If you have something along these lines:
Tab 1
Try adding return false; after the tab activation command:
Tab 1
My guess is that you are animating your tab transitions? I am having the same problem, where the page scroll jumps back to the top with every click.
I found this in the jquery source:
// Show a tab, animation prevents browser scrolling to fragment,
Sure enough, if I have this:
$('.tab_container > ul').tabs();
$('.tab_container > ul').tabs({ fx: { height: 'toggle', opacity: 'toggle', duration: 'fast' } });
my code jumps to the top and is annoying (but there's animation). If I change that to this:
$('.tab_container > ul').tabs();
//$('.tab_container > ul').tabs({ fx: { height: 'toggle', opacity: 'toggle', duration: 'fast' } });
there is no tab animation, but switching between tabs is smooth.
I found a way to make it scroll back, but it's not a proper fix, as the browser still jumps to the top after clicking a tab. The scroll happens between the events tabsselect and tabsshow, so the following code jumps back to your tab:
var scroll_to_x = 0;
var scroll_to_y = 0;
$('.ui-tabs-nav').bind('tabsselect', function(event, ui) {
scroll_to_x = window.pageXOffset;
scroll_to_y = window.pageYOffset;
});
$('.ui-tabs-nav').bind('tabsshow', function(event, ui) {
window.scroll(scroll_to_x, scroll_to_y);
});
I'll post any more progress I make.
I was given a solution for this...
How to stop screen from jumping up when tab is clicked:
Wrap the div that contains the tabs in a div with a fixed height.
See example here: http://5bosses.com/examples/tabs/sample_tabs.html
I had the same problem with jquery ui's menu - a preventDefault() on the anchor's click event stops the page from scrolling back to the top:
$("ul.ui-menu li a").click(function(e) {
e.preventDefault();
});
Mike's solution demonstrated the principle greatly but it has a big drawback - if the resultant page is short, the screen will jump to the top anyway! The only solution is to remember the scrollTop, and restore it after the tabs are switched. But before the restoration, enlarge the page (html tag) appropriatelly:
(edit - modified for new Jquery UI API + small improvement for large pages)
$(...).tabs({
beforeActivate: function(event, ui) {
$(this).data('scrollTop', $(window).scrollTop()); // save scrolltop
},
activate: function(event, ui) {
if (!$(this).data('scrollTop')) { // there was no scrolltop before
jQuery('html').css('height', 'auto'); // reset back to auto...
// this may not work on page where originally
// the html tag was of a fixed height...
return;
}
//console.log('activate: scrolltop pred = ' + $(this).data('scrollTop') + ', nyni = ' + $(window).scrollTop());
if ($(window).scrollTop() == $(this).data('scrollTop')) // the scrolltop was not moved
return; // nothing to be done
// scrolltop moved - we need to fix it
var min_height = $(this).data('scrollTop') + $(window).height();
// minimum height the document must have to have that scrollTop
if ($('html').outerHeight() < min_height) { // just a test to be sure
// but this test should be always true
/* be sure to use $('html').height() instead of $(document).height()
because the document height is always >= window height!
Not what you want. And to handle potential html padding, be sure
to use outerHeight instead!
Now enlarge the html tag (unfortunatelly cannot set
$(document).height()) - we want to set min_height
as html's outerHeight:
*/
$('html').height(min_height -
($('html').outerHeight() - $('html').height()));
}
$(window).scrollTop($(this).data('scrollTop')); // finally, set it back
}
});
Works with the fx effect too.
Try using event.preventDefault();. On the click event which is switching the tabs. My function looks like this:
$(function() {
var $tabs = $('#measureTabs').tabs();
$(".btn-contiue").click(function (event) {
event.preventDefault();
$( "#measureTabs" ).tabs( "option", "active", $("#measureTabs").tabs ('option', 'active')+1 );
});
});
Thanks for your help. Good suggestion, but I tried before with no luck. I think JQuery UI may be overriding my efforts.
Here is the code per tab:
<li class=""><span>Two</span></li>
I already tried this with no success:
<li class=""><span>Two</span></li>
Here is a simple example (without return false): http://5bosses.com/examples/tabs/sample_tabs.html
Any other suggestions?
Try just adding a min-height using css to each of the tab content areas ( not the tabs themselves ). That fixed it for me. :)
> var scroll_to_x = 0; var scroll_to_y =
> 0;
> $('.ui-tabs-nav').bind('tabsselect',
> function(event, ui) {
> scroll_to_x = window.pageXOffset;
> scroll_to_y = window.pageYOffset; }); $('.ui-tabs-nav').bind('tabsshow',
> function(event, ui) {
> window.scroll(scroll_to_x, scroll_to_y); });
Thanks for your help! Please let me know what else you find.
The above function works (screen doesn't move permanently)... but, the screen is very wobbly on click.
Here is a simple example showing how clicking a tabs causes the screen to jump toward the top (without the above code):
http://5bosses.com/examples/tabs/sample_tabs.html
Note that there's no animation being used.
I prefer to have an href="#" in my links that do not take the user anywhere, but you can do this as long as you add an onclick="return false;". The key, I guess, is not sending the user to "#", which depending on the browser seems to default as the top of the current page.
There is a much more simple way which I discovered from the comments on this page that is to simply remove the href="#" and it will not jump to the top any more! I verified and it works for me. Cheers
I had such a problem. My code was:
$("#tabs").tabs({
hide: {
effect: "fade",
duration: "500"
},
show: {
effect: "fade",
duration: "500"
}
});
I have simply removed show and it worked like a charm!
$("#tabs").tabs({
hide: {
effect: "fade",
duration: "500"
}
});
I had the same problem, plus mine were rotating on their own so if you were at the bottom of the page, the browser window would be scrolled up tot he top. Having a fixed height for the tab container worked for me. Kind of a weird thing still is that if you leave the window or tab and go back, it will still scroll. Not the end of the world, though.
replace the href="#" with href="javascript:void(0);" in 'a' element
works 100%
I found in my case the tab href=#example1 was causing the page to jump to the position of the id. Adding a fixed height to the tabs made no difference so I just added:
$('.nav-tabs li a').click( function(e) {
e.preventDefault();
});
Did you tryed:
fx: {opacity:'toggle', duration:100}

Categories

Resources