So I've got the following code:
$(document).ready(function(){
if(window.location.hash) {
$('body,html').animate({
scrollTop: $(window.location.hash).offset().top
}, 1000);
}
})
Which I've built with the help of code taken from StackOverflow.
I call the page at url#destination so actually it should scroll to the element whose ID is the page Hash. The element exists and the page scrolls down, but not to the exact element offset, but a bit more above. It could be just fine but I want it to work as I expected.
So I now show you the console results:
>>>$("body").scrollTop()
>1155
>>>$("#aboutus").offset().top
>1672.890625
Could someone explain this to me? Because I cannot understand anything here.
Hmmm... It works fine for me. Maybe the problem is, as a user pointed in the comments, the elements haven't loaded yet so you should use $(window).load(). But if you use that, your code won't work fine since the browsers have the built-in method that when a hash exists in the url, it goes directly wherever the element whose id is the hash is. This happens because this action is triggered before the .load event detection in your javascript code. So, if you want to make sure the code works, replace the targeting of the element with other attribute like:
$(window).on("load", function(){
if(window.location.hash) {
setTimeout(function(){
$('body,html').animate({
scrollTop: $('*[idt="'+(window.location.hash).replace("#", "")+'"]').offset().top
}, 1000);
}, 130)
}
})
This should make fully sure the animation works properly, since there's no element that has got such a hash, and the js code manages the same way.
The reason it doesn't scroll to the very bottom is because your last element hasn't been added to the DOM at the time of scrollTop execution.
Make scrollTop asynchronous to wait until the DOM has completely rendered:
setTimeout(() => {
element.scrollTop = element.scrollHeight;
}, 0);
Related
I'm using this jquery function to scroll into a div coming from a link at the index; when I execute the action (clicking on the link to go to the secondary page) and the scroll is executed, it works but not with the right 'scrollTop' measurement.
I realize that it works correctly until I reload the page. I do not know if I'm using the correct function.
var locationString = window.location.hash;
var headerHeight = -70;
$(document).ready(function(){
var divLoc = $(locationString).offset();
console.log(locationString, divLoc.top , divLoc.top + headerHeight);
$('html, body').animate({scrollTop: divLoc.top + headerHeight}, "slow");
});
The most common cause is the miss understanding of two event related to the page load: $(document).ready() (all elements of the DOM are ready to query/modify or whatever) and $(window).load() (all the images and related css are ready and the page will be rendered and will be fully displayed by the browser).
If you use $(document).ready() to apply actions that need all the page to be loaded for correctly display all the sizing, it will fail, because the images are not loaded yet so the vertical offsets (as in your case) may not be correctly computed.
So you need to use $(window).load() instead, so when you scroll to the element you will ensure that the page is fully rendered an all the elements will be placed as they should be.
Hope it helps.
I try to solved this problem but I don't understood where is the error.
I have and footer of all pages a to the visitors can comeback to the important part of the site whit slow animation.
In main page any problem that work correctly.
But in post page the animation didn't existe.
this is an exemple of page with the problem.
the code I used for the animation is this:
$(".gotof").click(function (e) {
var b = $(this).attr("href").substr(1);
console.log(b);
event.preventDefault();
$(".wrapper").animate({
scrollTop: $("#" + b).offset().top + $(".wrapper").scrollTop()-60
}, "slow");
console.log('e');});
First I think is the sibling of the element but no problem in this part.
After I try other functions for scroll to an anchor.
After multiples tests I control if something is not same in the two page but same Js, same plugin.
I don't understand what is the problem.
Please help me.
You're using event.preventDefault() - event is not defined, e is. Change it to e, instead of event, and it'll probably work. If you had looked in the browser console, you'd seen this. That might not be the error, but it will prevent the rest of the script to run.
After loading, I want a section of the page to be display on the top, so the page scroll will be in that particular place. without the user see scrolling, I want him see immediately the right place on the page.
I load the JQuery mobile script and this override the document ready and load events.
If I remove the JQuery mobile Script It works perfect. But I cant remove It.
I tried:
$(window).load(function() {
window.scrollTo($("#selector").offset().top, 0);
});
As mention in - Stackoverflow question I tried:
$(window).load(function() {
setTimeout(function() { $.mobile.silentScroll($("#selector").offset().top); }, 100);
}
});
But It didn't work for me.
only in chrome the scroll is in the right place, but in IE, Firefox It didn't.
If I increase the timer to 1000 the IE work but the user see the top of page and after the scroll go to the right position. and this is not good.
I tried:
$(document).on("pagebeforeshow", '#selector', function() {
$.mobile.silentScroll(500);
setTimeout(function() {
$.mobile.silentScroll(500);
}, 100);
});
And it didn't work too.
What Do I need to do to, for scroll the page to the right place in all the browsers, Immediately after page had been loaded.
Thanks for helping.
I wrote sample code in this jsfiddle, it works in Chrome and Firefox
Here is code that I used:
$($("html,body").animate({scrollTop: 500}, 1000));
Hope this help
EDIT: if you want scroll to be in particular place immediately after page had been loaded then use this code (see plunker sample)
$(document).ready(function()
{
$("html,body").scrollTop(400);
});
I have div with vertical scroll bar. Div is being updated dynamically via ajax and html is inserted using jQuery's .html method.
After div is updated scroll bar returns to top and I am trying to keep it in the previous position.
This is how I'm trying it:
var scrollPos = $('div#some_id').scrollTop(); //remember scroll pos
$.ajax({...
success: function(data) {
$('div#some_id').html(data.html_content); //insert html content
$('div#some_id').scrollTop(scrollPos); //restore scroll pos
}
});
This fails. My best guess is that it is failing due to inserted html not rendered (ie. no scroll).
For example this works.
setTimeout(function(){
$('div#some_id').scrollTop(scrollPos);
}, 200);
But this is dirty hack in my opinion. I have no way of knowing that some browsers won't take more then these 200ms to render inserted content.
Is there a way to wait for browser to finish rendering inserted html before continuing ?
It's still a hack, and there really is no callback available for when the HTML is actually inserted and ready, but you could check if the elements in html_content is inserted every 200ms to make sure they really are ready etc.
Check the last element in the HTML from the ajax call:
var timer = setInterval(function(){
if ($("#lastElementFromAjaxID").length) {
$('div#some_id').scrollTop(scrollPos);
clearInterval(timer);
}
}, 200);
For a more advanced option you could probably do something like this without the interval, and bind it to DOMnodeInserted, and check if the last element is inserted.
I will just like to point out one difference here: One thing, is when the .html() have completed loading, but the browser actually render the content is something different. If the loaded content is somewhat complex, like tables, divs, css styling, images, etc - the rendering will complete somewhat later than all the dom ellements are present on the page. To check if everything is there, does not mean the rendering is complete. I have been looking for an answer to this by myself, as now I use the setTimeout function.
Such callback does not exists because .html() always works synchronously
If you are waiting for images loading, there's one approach https://github.com/desandro/imagesloaded
I have some JavaScript that can appear on many different pages. Sometimes those pages have been accessed via a URL containing an anchor reference (#comment-100, for instance). In those cases I want the JavaScript to delay executing until after the window has jumped. Right now I'm just using a delay but that's pretty hackish and obviously doesn't work in all cases. I can't seem to find any sort of DOM event that corresponds to the window "jump".
Aside from the simple delay, the only solution I've come up with is to have the JS look for the anchor in the URL and, if it finds one, watch for changes in scrollTop. But that seems buggy, and I'm not 100% sure that my script will always get fired before the scrolling happens so then it would only run if the user manually scrolled the page. Anyhow, I don't really like the solution and would prefer something more event driven. Any suggestions?
Edit to clarify:
I'm not trying to detect a hash change. Take the following example:
Page index.php contains a link to post.php#comment-1
User clicks the link to post.php#comment-1
post.php#comment-1 loads
$(document).ready fires
Not long later the browser scrolls down to #comment-1
I'm trying to reliably detect when step 5 happens.
You can check window.onhashchange in modern browsers. If you want cross compatible, check out http://benalman.com/projects/jquery-hashchange-plugin/
This page has more info on window.onhashchange as well.
EDIT: You basically replace all anchor names with a similar linking convention, and then use .scrollTo to handle the scrolling:
$(document).ready(function () {
// replace # with #_ in all links containing #
$('a[href*=#]').each(function () {
$(this).attr('href', $(this).attr('href').replace('#', '#_'));
});
// scrollTo if #_ found
hashname = window.location.hash.replace('#_', '');
// find element to scroll to (<a name=""> or anything with particular id)
elem = $('a[name="' + hashname + '"],#' + hashname);
if(elem) {
$(document).scrollTo(elem, 800,{onAfter:function(){
//put after scroll code here }});
}
});
See jQuery: Scroll to anchor when calling URL, replace browsers behaviour for more info.
Seems like you could use window.onscroll. I tested this code just now:
<a name="end" />
<script type="text/javascript">
window.onscroll = function (e) {
alert("scrolled");
}
</script>
which seems to work.
Edit: Hm, it doesn't work in IE8. It works in both Firefox and Chrome though.
Edit: jQuery has a .scroll() handler, but it fires before scrolling on IE and doesn't seem to work for Chrome or Firefox.
To detect when the element appears on the screen, use the appear plugin:
$('#comment-1').appear(function() {
$(this).text('scrolled');
});