jquery AJAX backbutton problems - javascript

This is a bit weird to explain so ill do my best.
Im working on a mobile site that im trying to shape into an ios app (eventually).
On this page i have a menu button that on click, shows/hides menu.
Everything for the most part is working but, the problem is that when you click on the "back" button and the browser runs out of previous locations to go back to, the menu button breaks. When you click it, nothing happens. it behaves as though nothing is there.
The errors go like this, if on index(or first page), you click ONE link to go forward, and then on the browser hit the back button, it breaks instantly.
If your on the index, and hit for example, 5 links in any order(essentially you went forward 5xs) and thereafter, you hit back up to 4xs, the menu still works....you can essentially keep pressing links forward and be fine, hit back as far as you want and stop short one less than the total times you went forward and still be fine.
As soon as you hit the maximum backs, and theres nothing left in the history of page locations to go back to, the menu then breaks.
here is the link of this dummy site im working on (on my server)
NOTE: to test, when it loads, manually shrink the browser to about 400 width so you can see the page take effect.
EDIT** woops forgot the link
http://somdowprod.net/4testing/mobile/less1.html
and here is my code
javascript:(i left comments in there, so you can see where my logic is at...maybe im going about it wrong?)
// JavaScript Document
$(document).ready(function(){
var newHash = "";
var menuBtn = $('.leftButton');
//~~~~~~~~~~~~~~~~~~~~~~~~~~~menu show/hide
menuBtn.click( menuShowHide);
//===========================//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~MENU SHOW / HIDE
function menuShowHide(){
$('#menu').toggleClass();
// if($('#menu').css("display") == "none"){
// $('#menu').css("display","block");
// } else {
// $('#menu').css("display","none");
// }
scroll(0,0);
}
//===========================//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~ACTIONS FOR THE is-loaded trick.
function isLoaded(){
$('#progress').remove();
}
//===========================//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~ACTIONS FOR THE HOME PAGE
if(newHash == ""){
$('body').append('<div id="progress">Loading...</div>');//attach this div which is made to look like a loading bubble.
$('#contentHere').load('index.html #content', isLoaded);//load the content div from the index.html file
}
//===========================//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~Load the clicked content into my container via jQuery AJAX
$('#menu a').click(function(){
menuShowHide();
window.location.hash = $(this).attr('href');
return false; //doesnt let the link jump to a new page
});
$(window).bind('hashchange',function(){
newHash = window.location.hash.substring(1);
$('body').append('<div id="progress">Loading...</div>');//attach this div which is made to look like a loading bubble.
$('#contentHere').load(newHash, isLoaded);
//console.log(newHash);
});
//===========================//
});
Anyone have any ideas as to whats making the menu break? Thanks in advanced.

The hashchange event is known to be unpredictable with the browsers back button.
Here's what's happening. When you back all the way to the beginning, the whole less.html page is being loaded into its own 'contentHere' container, and since document.ready won't be called on this subpage, no menuButton.click handler will be assigned to the links, so clicking them will not do anything.
Although being able to use your browsers back and forward buttons on asynchronous changes would be a neat feature, I don't think people would miss it enough for you to try to hack a workaround. People are used to not being able to use the back and forward button on asynchronously loaded content. They would try it once, see that it takes them to your site's referrer, hit forward, and subconciously make a mental note to use your menu instead of the back and forward buttons.
Probably a better suggestion, however, is to get rid of the AJAX feature altogether and let the links act the way that people expect them to. Okay, so you lose the cool 'Loading' modal and you save the user a tiny bit of time, but then you aren't confusing people's expectations about your interface.
Edit: to answer your question below, instead of using load() to get static content (which is overkill), put all of the content as sections in your less.html file and hide/unhide it using the menu selections. Here are two ways to accomplish this, each with their own advantages and disadvantages:
Fix your header with CSS (including the menu) (example: lifeinthegrid.com/simple-css-fixed-header/) and then make your menu links normal anchor links with no JavaScript event handler. When you click a link in the menu, the content jumps to that section and because your header is fixed, it has the feel of being a very fast httpRequest. Advantages: minimal JavaScript, the browser's back and forward buttons will work. Disadvantages: fixed elements are a nuisance on older smartphones, the next section might sneak into the bottom of the viewport and ruin the illusion. Solution: put more space between them.
The other method is to use show()/hide() on the different content sections. So let's say you click 'about us'. All of the sections are hidden and the 'about us' content is shown. Advantages: It's not as annoying as a fixed element, you can spice it up with FadeIn()/FadeOut() or other JQuery animation effects. Disadvantages: your browsers history will not track these changes unless you do some window.location hackery.

Related

How can I have the page reload to the top of the screen? Right now it reloads to wherever they were before the reload

I am creating a website where I have to large content boxes that are absolutely positioned -- one at the top of the screen and one below off screen. I have the <body> element set to overflow-x and overflow-y none.
body {
overflow-x: hidden;
overflow-y: hidden;
}
When a button is clicked on the screen, the overflow-y changes to visible. This works just fine. However, if the user is near the bottom of the screen (as in farther down compared to when the page first loaded) and they reload the page, the user stays where they are but the overflow-y gets set to none and the user is stuck halfway down the page. Is there a way to have the user always start at the top of the page?
Also, this is completely vanilla js, html, and css -- no libraries or anything like that. If I need to add any other parts of my code let me know. Thanks
I have tried to use various methods of running code on load or before load (stuff like scrollTo(0,0) and the like). Having the page scroll before the reload works but does not look very good. It would be nice if it could just load at the top without the user actually seeing it move if that makes sense.
You would need some javascript to get that done. I recommend the following:
window.onbeforeunload = function () {
window.scrollTo(0, 0);
}
I found this solution on StackOverflow itself. Here is the solution
location.replace(location.href);
The above function replaces the URL with itself and then reloads the page, making the page start from the beginning. One disadvantage of this is, the previous History session for this page will also be replaced with a new one and the user won't be able to go back to the earlier pages using the back button on the browser. Check it here at MDN
Here is the link to the answer as well. (https://stackoverflow.com/a/65422431/10521908)
It's a default behavior of browser's that they don't scroll to top on refresh.
We have too manually do it.
window.onbeforeunload = function () {
window.scrollTo(0, 0);
}
For more refer this has the whole answer.
Note: Before posting a question, look if its already answered.

How to implement "Skip to content" accessibility functionality on React?

When we are using keyboard only and tab through the website, the first anchor link for "Skip to a content" is shown to skip the navigation and focus to the main content which makes the web page accessible. It is easy to add such a feature on multi-page website where there is full page reload and the focus for the page resets. I am looking similar behavior on the React. How can we implement such behavior on a Single page application built on React?
I disagree with Graham that you shouldn't need a skip to content link. In a SPA, when the user navigates to a new "page," the focus remains on the link that was pressed. Every time your user wants to navigate, they're going to have to go through the remaining nav menu to get at the content.
You could either move focus to the beginning of the document so they hit your 'skip to content' link each time (has its merits because it's most like multi-page apps which they're likely to be familiar with) or move it to the content body itself and save them a click (seems more streamlined to me, but might be unfamiliar to your users).
componentDidMount() {
setTimeout(() => document.getElementById('your-element-of-choice').focus(), 0)
}
I'm leaning toward the latter, but this will work either way you decide to implement it. Don't forget to set the tab index on the element you want to focus on to -1 as well.
You shouldn't need a skip to content link on a SPA other than the one you already have (for first time load for return visitors).
Skip to content is for when you click a link to a new page, it helps avoid having to listen to the menu every time you navigate.
With a SPA that isn't an issue as everything is done via AJAX, when I click a link a region on the page will get updated with new content.
All you need to do is move focus to the region that is being updated from the menu item.
Certain screen readers will need explicit ARIA Live Regions in order to register the new content so make sure you test it with a screen reader.
Where you will run into accessibility problems pretty fast in SPAs are when you start thinking about delays.
What happens if I click that link and the page takes 3 seconds to load?
What happens if the page doesn't load at all?
Those are your bigger challenges with a SPA.

When loading, the page goes on the bottom of it

I have an issue with my website. My page loads normally in Firefox, but when I use either Chrome or Safari, it goes to the bottom of the page and I don't understand why. I tried putting the following snippet at the beginning of the page, but no luck.
<script>
$(document).ready(function() {
$(document).scrollTop(0);
});
</script>
Why does the page go to the bottom on loading?
When going to your site, I get redirected to http://www.ondinevermenot.fr/#start. That means the page will try to jump to the start element.
However, the start element is absolutely positioned. Therefore, when the page tries to jump down, the start element moves down with it. Therefore the page tries to jump down again. Then the start element moves down more. They keep going down until the bottom of the page, when there is no more room.
To fix it, don't redirect to #start when your page loads.
Because of the strangeness of jumping to something that's absolutely positioned, it's probably handled differently in different browsers.
Try to have your image and other contents put inside div and set the box attribute of the div to margin:auto. works well with HTML5.
i have an alturnative work around for you and incase you ever need to get to the top of the page - you can use this javascript as an alturnative:
((IJavaScriptExecutor)webapplication).ExecuteScript("window.scrollTo(0, document.body.scrollHeight 0)");
however the other option would be to set a start up property: for example document.start("body.height = 0") something along those lines may work.
preferably id use option one as a code to start the broswer at a set height may not work so well for every browser. hope this helps.
I had 2 links to my home page in my footer. When I removed the links from my footer the problem went away.

Repainting a page in Chrome?

I've been looking at using a script I've found online (here) as a basis for a website I'm looking to create. It has an issue in Chrome in that the page wont scroll once a link is clicked, however if I resize the window just a tiny bit the page "repaints" - I think this is the right term - and all is well again.
Is there anyway to do a repaint like this? I don't mean refresh :)! Sorry if this seems a bit vauge, if you try this link in chrome, press one of the links in the header and you'll see the problem when trying to then scroll.
Initially I'm thinking there might be some javascript I can call at the end of switching pages that repaints the page.
Thanks
You could try doing something like this after the slide has completely transitioned to a new page:
Since you've commented that it didn't work as I originally suggested, here's a way to "encourage" Chrome to do the hide/display trick:
$(".slide.loaded.prev").css("display", "none");
setTimeout(function() {
$(".slide.loaded.prev").css("display","");
});
or you could try this:
var slide=$(".slide.loaded.prev");
slide.css("display", "none").height(); // just get the height to trigger a relayout.
slide.css("display", "");
The above code simply finds the previously visible slide, sets the CSS property display to none (hiding it completely) and then removes it. This trick worked when using the Chrome developer tools.
It appears that the scroll bar is for the previous "slide" in Chrome. By toggling the display of the slide briefly, the scrollbar is hidden under the now current "slide's" content.

UIWebView scrollTo should behave smoothly

I do not know if i asked correctly in Question Title, but here i am going to describe in brief
I have an UIWebView and loading the content based on div and each div has unique id on loadRequest.
As though my content was too large so i break down into pieces and loading the remaining content once you tap on 'Read More'
This 'Read More' event fire on autoscroll which i am handling through javascript. so once that event is fired it just append data (for which i have another method) by using window.location.href = div1+div2(its just an example).
Now the main problem is when i scrollDown and wherver i get the 'Read More' message and it auto fire then it adds the data to the current div and show (User feel its an continue reading) but when
I scroll towards to up
It behaves weired because it just append the data to the div and scroll to setYScroll(updatedlocation);
updatedlocation is used for when we are adding the content to the div and it should scroll to the same position where the user was.
so lets start with an example, assume currently i am reading the div2 and when i scroll up'Read More' events fired and add div1 to div2 and then web view delegate shouldStartLoadWithRequest called.
so every time its update the content to div2 when you are scrolling up but first it takes me the previous s location of div1 and then take me to div2 location where i was currently reading.
so it feel like really weired, suddenly it takes me to somewhere for a while and take me to my current position within friction of second
I tried with this solution,
I thought to take the screen shot and create an imageView with that screenshot image of the current UIWebView and put on webview whenever 'Read More' event is happening. once the web view loading is done remove the imageView and display the webview.
but this is happening in the same way, the problem is every thing is happening under the webview delegate. i still could not figure out whats happening? The solution of this problem am i on right trackj or is there any better solution for that
I have a similar situation. What I do is have two UIWebViews on top of each other. When it is time to update one view, I grab the scroll position, load the new data in the hidden UIWebView, when the other UIWebView is done loading its data it sets its scroll position to the current scroll position of the first webview, then hides the first webview and unhides itself.
Its pretty seamless and works very well.
I suspect that the "jump" you experience depends on the fact that the web view is fully redrawn (and we all know that UIWebView is slow).
So, I see 2 options:
implement the "Read more" mechanics fully in javascript by means of Ajax;
instead of loading data into the view using loadRequest, make a NSConnection to that url and then update the web view by injecting in it the HTML you got from NSConnection through stringByEvaluatingJavaScriptFromString.
The second option is possibly nicer because it is fully SDK based, but you will readily see that it is far more complex than the first one. The two of them will work and I am pretty sure that will give you the kind of smooth behavior you are after.
If I understand your question correctly it sounds like you're trying to implement your own handling of the "infinite scroll" concept.
It might be worth your while to check out one of the many infinite scroll libraries that are already out there. If one doesn't fit your requirements perfectly you might find the inspiration you need to fix the one you have now.

Categories