Why is it that when I visit my jQuery mobile page, lets say page.php it shows up fine, but when I visit the same page page.php#someDetailsHere it just shows a white page?
And how can I fix this?
I use a third party app that redirects to my webpage with the # added to the url..
Edit: I stepped through your page to see what was going on.
Your grief is caused by jQuery Mobile. When the page loads, it detects this as an "page change", and because jQuery Mobile uses the hash (#) to emulate the back-button for AJAX requests, it also has some special handling for pages that it sees are loaded with a hash.
The bottom line is that it sees a page load, decides it should "reject" it, and prevents anything further from happening.
My guess is that the jQuery Mobile team didn't expect anyone to load a mobile page with a hash on init, since the code seems to assume that the first load of the page will not have one.
To follow this yourself, set a breakpoint in the function isEmbeddedPage in jquery.mobile-1.0.min.css.
A possible solution would be to somehow prevent the jQuery Mobile code from running when the page initially loads. This might break other stuff that jQuery Mobile provides, though.
As says It turns out jQM parses hashes for its own purposes and just freezes if it can't make sense of them on load (unnecessarily aggressive behaviour if you ask me, they should at least fire a custom event — although there is a high priority issue reported for it on GitHub).
One solution is to disable jQM's hash processing: before DOM ready, execute the following:
$.mobile.hashListeningEnabled = false;
Note this will necessarily break any functional reliance on jQM's history polyfill on browsers that don't support history pushState (IE etc).
Related
I'm working on my first jQuery Mobile site, which is a (prototype for) a Location Based Game in Brisbane, Australia: www.jsjensen.dk/soleil/
My question is based on viewing from a mobile device, but a desktop device have very similar problems. I have tested with Chrome and Safari on iPhone, iPad, and Mac. Same problem everywhere.
I think it's related to how jQuery Mobile loads and displays pages, but I'm not using multiple pages in one HTML document, but have multiple HTML document.
If you go to the website above and then click "QUESTS" in the menu, followed by "Stairway to Knowledge" you will end on /soleil/quest01.html (desktop) and /soleil/#/soleil/quest01.html. That "#/soleil" really confuses me!
In this first try the JavaScript for handling answers in the text input is not loaded. That means nothing happens when you press "Unlock".
Now, if you reload on desktop or edit the address on iOS to /soleil/quest01.html (which is the actual and real file) it will reload the page with the right JavaScript loaded and initialized.
Now I'm able to go back (pressing "QUESTS" in the menu) and then go to another page (e.g. "Citadel of Fun") with the same problem: the JavaScript not loading. If I go back to the other one ("Stairway to Knowledge") the JavaScript is, however, still loaded and working just fine.
So what happens here? I'm pretty sure my linking/coding is correct, but it's just a basic understanding of jQuery Mobile that I'm missing. Can I change something to make this work? It could really be awesome!
So, I found a way to fix it, but not really a solution to the original problem.
I've added rel="external" to the tags pointing to the pages where I had problems. In this way it will not use the AJAX system to load these pages, but do it in a regular way. This solved my problem, but now I can't make any fancy transitions.
We have a problem with IE. On a web page with a form, multiple frames are created via javascript. This is due to some crappy WYSIWYG. The problem is that when the user clicks on the browser "back" button, you'd expect the entire page to go back. This is what happens in FF, Chrome, Opera, Safari, etc. But for IE, you have to click the back button for each frame on the page, even if you don't do anything else but load the page.
Knowing that sometimes +20 frames can be on the same page (many textfields), this is a real pain for users.
The question: how do you make the browser back button work for the main page, regardless of the amount of frames you have on the page ?
Thanks so much !
One way of doing it is to implement clientside routing using hash bang urls.
Every time a page is changed on an iframe the hash part of the parent url is changed to reflect it.
You then have some js that listens for these changes and does what is needed to updated the full page state across frames.
Now when the user pushes the back button, the parents url changes to the hash it was before the last change in the child iframe, and everything is updated accordingly.
Be aware: that this is a non-trivial thing to implement if you have many iframes, and i can't give you a working script that will fix your problem. This is meant for inspiration only.
(following Martin Jespersen response)
Yes, I also thinks that it is only solution. And it is hard to implement, but there is a lot of good libraries to handle # changes.
The lightweight jQuery solution: http://tkyk.github.com/jquery-history-plugin/.
Very complex solution with ExtJS: http://dev.sencha.com/deploy/dev/examples/history/history.html#tab1:subtab1.
And I think, that is not possible to do it realibly cross-browser without javascript.
I am facing a very strange issue. I have tabs and subtabs in my html and when i click on a tab/subtab 'activeContent' class is placed on it. if i click on another tab/subtab the 'activeContent' class is removed from the previous tab/subtab and placed on the current one. While this scenario works fine when i keep clicking on multiple tabs/subtabs. But in IE8 its very slow. Especially when i hit the back button, the content from the previous subtab is loaded but the active subtab takes a lot of time to change its class. The effect of it is that while that while the content if of some other tab while the active subtab is still the previuos one.
I have even tried to first change the tab/subtab class, something like
$(currentTab.node).removeClass('activeContent');
$(tab.node).addClass('activeContent');
and then used a seTimeout , something like after the above code gets executed.
setTimeout(fuunction(){
//load ajax content
}, 800);
Even then the tabs/subtabs takes a lot of time to change its class.
Is this a IE8 or i might i have to optimize my code. I am not sure. Everything works fine in all other browsers including IE6. Is it has something to do with the back button in IE8?
Are you calling this code when you hit the back button? Most likely the back button is causing a page refresh, and you are waiting for the whole page to reload. IE8 is probably just making this behavior more obvious, because it is handing the caching of page content a little differently.
I have an alternative solution for you. Is this a click event on an anchor tag? I have noticed that it takes an exorbitant amount of time for IE to cancel the default action on an anchor tag that has a href property. Especially in IE8.
Here is an example function from my site:
function SwapLinks() { // This allows our pages to degrade gracefully. But hrefs are slow. So, if JS is enabled remove the href!
$(".playerLink").each(function (index) {
var link = $(this).attr("href");
if (link != undefined && link != null && link != "") {
$(this).removeAttr("href");
$(this).attr("link", ""); // This little number makes IE6/IE7 happy.
$(this).attr("link", link);
}
});
Then you would add a click event on (".playerLink") that handles the Ajax updating.
There was no problem with my code actually. I tested on a friends machine and it was working fine. Then i reset IE8 and everything started to work fine. I am not sure why IE8 was behaving in that way. It happened earlier also, I had to reset IE8 because it was not recognizing the app running on jboss server on my local machine by doing this http://my-pc:8080/myapp/mypage.html BUT rather i had to do http://167.232.23.12/myapp/mypage.html and then it would display evrything. So when i reset the browser , i could run my app through
http://my-pc:8080/ .
I had this problem too, and it turned out it was because I was forgetting to return false; from the click() event. (I imagine e.preventDefault() would work, too.)
I'd been using a link like <a href="#"> for my tabs since it doesn't really navigate anywhere, but IE seem to be "trying" to navigate and taking time to do so, so returning false prevents the navigation for real. (And is probably a best practice, and let's me put in "real" links to fall back to which is probably also a best practice.)
It seems especially a problem when I've loaded the page with a file:// URL on my development machine (as opposed to deploying it to a server and accessing it in the regular way via HTTP).
(Thanks to Jeff Davis and kd44 whose answers above put me on the right track.)
I have a website that uses a long-polling comet connection. The connection needs to be setup on/after page load.
Despite my efforts to prevent it, many browsers consider the long-poll request to be part of the page loading mechanism, thus keeping the page in a 'loading' phase. In Safari this results in the progress bar (behind the url field) to not complete. In Chrome the favicon is shown as a spinning loading icon. Even more problematic is mobile safari on iphone, that does not allow hiding the url field while 'loading'. Mobile android has similar issues on some devices.
All in all, the behavior is difficult to reproduce and seems to be dependent on browser/platform/connection speed/etc. Right now, my code initiates the long polling 10msecs after the window.onLoad trigger. This seems to work well often, but not always. I suspect it may have something to do with loading some external (image/javascript) resources, yet one would say the onLoad event is fired after these are completely loaded.
Anyone some pointers on how to force these browsers into considering my page as loaded? Ideally, one could somehow mark an xmlhttprequest as comet-like, but this is no feature :).
I've been having the same issue and found that if you allow the page to exit its onload handler before issuing your long polling ajax request, everything works fine and the page does not go back into a loading state.
So for example, what usually would be
$(document).ready(function() { $.ajax(...); });
would become
$(document).ready(function() setTimeout(function() { $.ajax(...); }, 0); });
In the particular case of WebKit, I believe that $(document).ready is a synonym for window.onload. So that's why it matters.
This worked for me on iPad1,1 with iOS 5.
We have been successful removing the "loading" indicator in Safari 5.1.5 with ajax long polling requests. Chrome unfortunately still consistently shows the loading indicator. For chrome, our team has chosen to simply change the css cursor value on the entire body element (ex: crosshair or a custom cursor) - a terrible "hack" - but at least the user won't see the loading mouse cursor while they are on the system.
Currently I am developing a web application for which I am using a pre-loader icon. What I want is that the pre-loader becomes visible every time the user navigates to another page or refreshes the page. So far I have the following solution:
window.onbeforeunload = function() { $("applicationdisabler").show(); };
For Safari and Firefox it works fine when the user clicks a link or refreshes the page. However in IE7 the div only becomes visible when the user clicks a link and NOT when the user refreshes the page.
The user can refresh the page by hitting F5 (on Windows) or any other possible way the browser provided.
Of course I have been looking for some workarounds already. The following code shows the alert in IE7, but the div still doesn't become visible.
window.onbeforeunload = function() { $("applicationdisabler").show(); alert("come on!"); };
The code of my div:
<div id="applicationdisabler"><img src="images/preloader.gif" /></div>
Hopefully someone can help me out.
You need to put the # before the id on the jQuery selector:
$("#applicationdisabler").show();
Why not use just use the onLoad listener instead? Although it would be slightly slower it should be more reliable.
Actually after a bit of looking around I'm not sure modifying the DOM makes any sense unless the onBeforeUnload handler returns false first - i.e. forces the user to stay on the same page.
As I understand it the onBeforeUnload event is fired just before the page is unloaded, so if you don't return false the browser will unload the page and DOM, and any JavaScript executed after that will be pointless.
That doesn't quite explain why JavaScript isn't executed properly in the onBeforeUnload function, but from what I've seen sites only use the window.alert or window.prompt dialogs to ask the user if they want to leave the site, and then often executing JavaScript if the user decides to stay.
Hence I'm guessing that some browsers may not allow DOM manipulation when this event is fired - since if the page is unloaded any DOM manipulation done is completely pointless.
So either:
Return false in your onBeforeUnload method, and then show your preloader (although this will stop navigation to the next page)
Use the onLoad event of the next page to show the preloader image instead
Also note: Opera versions 9.5 and below do not support this event (I'm unsure about later versions) but GMail does manage to catch the back button in Opera.
Possibly related is this security warning for IE7's implementation of the onBeforeUnload event - it's possible Microsoft patched it in a way that prevents the things you're trying to do. And I know IE6 and below don't allow commands like document.location='' in the onBeforeUnload handler for security reasons.