Scrolling a page using location.hash in Safari - html

I have a forum page that displays a tree view of messages below the currently selected message. When you click on a message in the tree the new message body is loaded into a div near the top of the page using AJAX and then the following code is run:
window.location.hash = "page_top";
Of course "page_top" is an anchor element near the top of the page, so the newly loaded message body scrolls into view.
This works fine on all the browsers, except Safari. On Safari (tested on PC and iPhone) it only works the first time you set location.hash. If you set it again the page does not scroll.
The end result is that the newly loaded message body does not scroll into view in Safari and you have to scroll back to the top of the page every time you pick a new message from the tree.
Why does Safari not like this and is there anything I can do to fix it ?
Edit:
I'm guessing this is related to a bug that you can find by Googling about location.hash and Safari. It seems Safari used to have a bug where if you set the hash to the same value twice it would cause it to reload the page. I'm guessing when they fixed that bug they fixed it a little too thoroughly and stopped it doing anything when you set hash to the same value again.
http://www.howtocreate.co.uk/safari/locationHashBug.html

You could reset it first:
window.location.hash = "";
window.location.hash = "page_top";

I needed to add:
<div><a name="page_top"></a></div>
<div><a name="page_topnot"></a></div>
Using "a name" instead of "a href". Works great!

Answering my own question. Gumbo was on the right track, but not quite there.
Safari doesn't like location.hash being set to a blank value. Instead you need to set it to a real anchor value.
So along at the top of the page I now have:
<div></div>
<div></div>
I found that I needed the divs around the anchors otherwise Safari was scrolling to an unpredictable part of the page rather than to the anchors.
Then to scroll to the top of the page I have to do:
window.location.hash = "page_topnot";
window.location.hash = "page_top";
With that in place Safari will scroll to top of the page every time.

I had the same problem as you had and this solution worked - the only thing I noticed was that in IE, I could hear two clicks - So I did a variation of yours and just put one anchor and it worked as well (ie, call twice, the first time, a non-existent anchor, the second time the real one)
On top, my anchor:
(tag a)name="top" id="top"(end of tag a)
Within javascript, the two calls:
window.location.hash ="topnot";
window.location.hash ="top";
Thanks for your help!

Related

History pushState inside iframe, affecting parent window layout in Chrome?

I have an iframe in which the pushState is triggered in order to provide the user with the ability to browse back and forward.
This iframe has some transform applied to it, and the parent window responds to mouse move updating the perspective-origin.
See the page in question.
All is fine in Safari, but when browsing back in history with Chrome, the layout of the parent breaks horribly. This sounds crazy to me, as the iframe contents shouldn't ever influence the layout of the parent window.
To test you can browse a few tabs inside the iframe, then click the back button in the browser.
Also note how if you go to "People" tab, and open any of the persons with a picture, the "Back" button in the top left calls the same function bound to pop state (furnax.goBack), without affecting the parent window.
Either this is a bug, or browsing back the history does more than I think.
I hope anyone has some insight.
Popstate handler:
$(window).on("popstate", function () {
if (furnax.popStoryEnabled) furnax.goBack();
});
goBack function:
goBack: function () {
var myHistory = tempDb.getItem("prev").split(",");
var to = "";
if (myHistory != "") {
to = "#" + document.getElementById(myHistory[myHistory.length - 1]).id;
} else {
to = "#" + $(".view").first().attr("id");
}
furnax.load(to, "pushright", true);
myHistory.pop();
tempDb.setItem("prev", myHistory.toString());
},
This is happening for me in both Chrome 41 and Safari 8 on OS X 10.10.2. I don't think the issue is with pushState. I believe what's happening is that when you change the URL in the iframe, the browser sets focus on the iframe and auto-scrolls the document to show the full iframe.
I believe it's similar to a bug I'm experiencing with focusing on inputs inside a CSS transformed iframe. Webkit bug #143100, Chromium bug #470891.
I'm not sure if your situation qualifies as a bug, as I believe it's intended behavior for browsers to do everything they possibly can to show focused elements, even if that means scrolling an overflow:hidden element. Then again, I'm not positive the iframe is actually receiving focus, it might be a different issue that just has some overlap.
One thing I would try is to make the pop state handler move the "iPhone" to the center of the window, and only change its URL after it has finished animating. If that doesn't work, maybe you can take a look at the example page I reference in my bug reports. It might give you some additional insight into the nature of the automatic scrolling.

jQuery "get" not loading content completely

I have my main file loading a second php file like this:
$.get('single.php?admin=1&start=1').success(function(data) {
$('.loader').fadeOut(400, function() {
$('#overlay').html(data);
$(".content h2").css({"padding-top": "50px"});
});
});
The overlay is filled with the content from the "single.php" page, when I view the HTML with the Chrome dev tools. And I can see the menu at the top of the page, but the main content doesn't show. When I load the page manually (http://bit.ly/1dCHTEp) the content loads every time perfectly.
Here is the page where the problem exists:
http://bit.ly/11U9OzC
Try clicking on the "expand" icon in the bottom right of any of the house divs, and you'll see the problem. If you click on the next arrow, in the top menu, it will load the 2nd div ok, and you can go back to the first div too.
This problem exists in Chrome (and also on my iPhone), not in Firefox (FF seems to work properly) and there are no errors in the dev console in Chrome. What am I doing wrong?
I checked out your site, and looking at the HTML - all the content IS THERE, it is just hidden (it has CSS set to display:none). I suspect whatever plugin/library/whatever you're using is setting it to display:none when you don't intend it to.

Chrome behaves differently when pressing reload v pressing enter in URL field

Was just trying to cobble a quick site together as a favour for my sister. It's based on a template she bought and I've just quickly bunged her copy/pictures in, so I'm aware the markup is far from perfect. That said, I can't see how it would be causing the following issue...
The template uses a jQuery plugin called jScrollPane to make the content sections scrollable. Sometimes however, in Chrome (v20) this doesn't work - it doesn't let you scroll all the way down.
What's really odd though, is the pattern I've found that seems to effect whether it works or not. Try the following
Go to http://mattandkate2012.co.uk in Google Chrome - click 'Ceremony' - can you scroll down far enough to see the map? I can't.
Press the reload icon, click 'Ceremony' - can you scroll down? I can't.
Select the URL in the browser URL bar, press enter - can you scroll down? I can now!
Does everyone else get the same results as above, and do you have any idea why pressing enter in the URL bar has a different effect to the reload button?
This functionality works fine in Firefox and even IE!
Thanks
Pete
From a very quick look I guess it's because the section contains an image and you aren't re-initialising jScrollPane once the image loads. See:
http://jscrollpane.kelvinluck.com/image.html
The difference between refreshing and pressing enter in the location bar is that the cached image is shown when you press enter in the location bar...
I would suggest moving the call to $('.content').jScrollPane({showArrows: true}); to inside the $(document).ready block - if you call it before the document is ready often images or other elements won't have loaded and so the height of the containers will be wrong.

Chrome vertical scrollbar not working when URL has # at end

I've had an intermittent problem that I thought was due to un-cleared floats. What happens in Chrome (my main development browser) is the vertical scrollbar will lock in the top position and I cannot scroll down the page. Initially when the page starts to load it will allow you to scroll and then when the page is loaded it will jump back to the beginning and lock itself.
I've just been ripping apart my pages looking for un-cleared floats and missing tags and finally found out that it is due to a URL having a # at the end (which gets programatically added and remains when I refresh the page).
This issue only happens in chrome - does not appear to happen in other webkit browsers.
I assume its looking for an anchor and not finding it and then giving up. Its definitely a bug but was wondering about a workaround, or why it is only doing it on my site - I can't duplicate it for instance here.
Shift click the URL to open in new browser:
URL that will lock : /faq#
URL that doesn't lock (same but without the #): /faq
For me, the solution was in a popup div's style: I had to make sure a div with a z-index and no float but surrounded by floating divs was given the style float:none and an explicit width (floating this was not needed as it was absolutely positioned). I have a thread working through this here.

Why do page anchors sometimes miss?

On an HTML page, a link like this:
Location on Page
...should navigate to this spot on the page:
<a name="pagelocation">
But in my experience, it sometimes misses - especially when linking from another page (like <a href="somepage.html#pagelocation">). By "misses," I mean it scrolls to the wrong spot on the page - maybe close, maybe not.
Normally, the target location ends up at the top of the screen. I know this can fail if there's not enough room below the anchor to scroll it to the top of the screen.
Why else would it fail? Does it depend on layout at all? How can I fix it?
(I'm keeping this general because I'd like a catch-all reference answer.)
Update 1
Thanks for the pointers so far about non-explicit image sizes. But what about on a page where all the elements have explicit size? (I'm dealing with one now.)
Quite often the scrolling can occur before the page has finished loading. If you have images without widths and heights, the page will jump, then load the image and re-layout itself, making the place you previously jumped to seem wrong.
Edit: Anything else that can change page layout should also be considered with suspicion... this include javascript and CSS that's not loaded in the <head> (never mind that all CSS should be loaded in the head; it isn't always).
If the page is bounced through a redirect, I believe IE will scroll the end page but Firefox won't.
JS Solution
Run this function on document ready.
function goToAnchor() {
hash = document.location.hash;
if (hash !="") {
setTimeout(function() {
if (location.hash) {
window.scrollTo(0, 0);
window.location.href = hash;
}
}, 1);
}
else {
return false;
}
}
I believe the behavior you are seeing is the result of the browser locating to that spot on the page before all images have finished loading. Once the images finish loading, then the layout of the page has changed (the page is likely longer vertically, for example), causing the location of where the anchor should be to have changed - but the browser still thinks it has already navigated to that anchor.
As mentioned above, this is probably due to images being rendered late and 'adjusting' the layout as they load.
If you can specify the size of the images then that much room can be allocated before they render, which should prevent the problem.
As a side note I've had this problem before in the form of using forward/back between enough pages that the images needed reloading, causing me to end up in the wrong place after they had rendered.
I have also seen this happen when JavaScript creates a drop-down menu at the top of a page. Then, once the menu has been finished, it is hidden, scrolling up the content below.
In the meantime, the browser has already set the target location at the top of the window. Hiding the menu a the very top of the page moves the target location up off the top of the window.
Note that you can add id="pagelocation" to just about any HTML element, for the same result, which saves you adding the additional anchors for link destinations.
OK. I think this is new. Using HTML5's autofocus will cause a misfire, as will jQuery's focus() method. Took 90 minutes of trial and error to discover this because I thought the issue was image related :)