JavaScript in jQuery mobile not working unless I refresh - javascript

I'm having a jQuery mobile page with JavaScript inside. The problem is the JavaScript doesn't work unless the page is refreshed. Here is my code:
jQuery(function($) {
var url = window.location.search.substring(1);
$('#mydiv').load('real_news.asp?' + url);
});

To understand this problem you need to understand how jQuery Mobile works.
Your first problem is point where you are trying to initialize JavaScript. From your previous answers I can see you are using several HTML/ASP pages and all of your javascript is initialized form the page <head>. This is the main problem. Only the first HTML file should have JavaScript placed into the <head> content. When jQuery Mobile loads other pages into the DOM it loads only the <div> with a data-role="page" attribute. Everything else, including <head>, will be discarded.
This is because currently loaded page has a <head> already. No point in loading another pages <head> content. This goes even further. If you have several pages in a second HTML file, only the first one is going to be loaded.
I will not try to invent warm water here so here are links to my other 2 answers discussing this problem. Several solutions can be found there:
Why I have to put all the script to index.html in jquery mobile (or in this blog article)
Link fails to work unless refreshing
There's more then enough information there to give you an idea what to do.
The basic solutions to this problem are:
Put all of your JavaScript into a first HTML/ASP file
Move your JavaScript into <body>; to be more precise, move it into a <div> with data-role="page". As I already pointed out, this is the only part of a page that is going to be loaded.
Use rel="external" when switching between pages because it will trigger a full page refresh. Basically, you jQuery mobile that the page will act as a normal web application.
As Archer pointed out, you should use page events to initialize your code. But let me tell you more about this problem. Unlike classic normal web pages, when working with jQuery Mobile, document ready will usually trigger before page is fully loaded/enhanced inside the DOM.
That is why page events were created. There are several of them, but if you want your code to execute only once (like in case of document ready) you should use the pageinit event. In any other case use pagebeforeshow or pageshow.
If you want to find out more about page events and why they should be used instead of document ready take a look at this article on my personal blog. Or find it here.

Your question isn't exactly overflowing with pointers and tips, so I'm going with the thing that immediately sprung to mind when I saw it.
Document ready does not fire on page change with jQuery Mobile, due to "hijax", their method of "ajaxifying" all the links. Try this instead...
$(document).on("pageshow", function() {
var url = window.location.search.substring(1);
$('#mydiv').load('real_news.asp?' + url);
});

Try pageinit like this
$(document).delegate("body", "pageinit", function() { // Use body or page wrapper id / class
var url = window.location.search.substring(1);
$('#mydiv').load('real_news.asp?' + url);
});

seems like nothing ever worked for me. Tried many different fixes, but i made the site too messy, that even position of certain javascript files wouldn't make the site work. Enough talk, here is what i came up with.
// write it in head at top of all javascripts
<script type="text/javascript">
$(document).ready(function() {
// stops ajax load thereby refreshing page
$("a,button,form").attr('data-ajax', 'false');
// encourages ajax load, hinders refresh page (in case if you want popup or dialogs to work.)
$("a[data-rel],a[data-dialog],a[data-transition]").attr('data-ajax', 'true');
});
</script>

Related

Include code from jQuery load() onto page source code [duplicate]

Many aspects of my site are dynamic. I am using jquery.
I have a div which once the DOM is ready is populated using load().
Then if a button is clicked, using load() once again, this value is replaced by another value.
This kind of setup is common across my site. My homepage is essentially lots of dynamically loaded, refreshed, and changeable content.
What are the repercussions of this for SEO?
Ive seen sites where each page is loaded using load() and then displayed using the animation functions... It looks awesome !
People have posed this question before, but noone has answered it properly.
So any ideas? JQUERY AND SEO??
Thanks
EDIT
Very interesting points. I dont want to overdo my site with jaascript.. just where neccesary to make it look good - my homepage however is one place of concern.
So when the DOM is readY, it loads content into a div. On clicking a tab, this content is changed. I.E No JS, No content.
The beauty here for me is that, there is no duplicated code. Is the suggestion here that i should simply 'print' some default content, then have the tabs link to pages (with the same content) if JS is disabled. I.E sacrifice a little duplicate code for SEO?
As far as degrading goes, my only other place of concern is tabs on the same page.. I have 3 divs, all containing content. On this page two divs are hidden until a tab is clicked. I used this method first before i started playing with JS. Would it perhaps be best to load() these tabs, then have the tab buttons link to where the content is pulled from?
Thanks
None of the content loaded via JavaScript will be crawled.
The common and correct approach is to use Progressive Enhancement: all links should be normal <a href="..."> to actual pages so that your site "makes sense" to a search spider; and the click() event overrides the normal functionality with load() so normal users with JavaScript enabled will see the "enhanced" version of your site.
If your content is navigable when JavaScript is turned off, you'll be a good ways toward being visible to search engines.
Note that search engine crawlers won't be submitting any forms on your site, so if you have any or elements that are meant to be navigating between your site's content pages, that content is not navigable by search engines.
Here is a guidelines how to make Google to crawl content loaded with ajax: http://code.google.com/web/ajaxcrawling/docs/getting-started.html
I use jquery load() asynchronous page load. It greatly improves user experience, but not seo-friendly. Here's the only solution I have found so far:
On first load I do not use jquery load() and try to write cookie with javascript.document.cookie = 'checkjs=on';
On next page load if php script finds this cookie it means that javascript is enabled and jquery load() can be used. If there's no such cookie then javascript is off (probably spider came), so jquery load() is not used.
if (!$_COOKIE['checkjs'] || $_COOKIE['checkjs']!='on'){echo 'js is off, hello Google!'; } else {echo 'js is on, can use jquery load';}
This way I can be sure that most of users can benefit from asynchronous page blocks load, exept for the very first load. And spiders get all content too.
In your case you could just load the same page with new parameter that makes another tab active. Spider is gonna be happy.

Why I have to put all the script to index.html in jquery mobile

I have used $.mobile.changepage to do the redirect in my phonegap+jquerymobile projects. However what makes me confused is that I need to put the script of all the pages to the same file index.html. If not, the redirect page can not execute the function in its header.
for example, my index.html seem to be
$(document).bind("deviceready",function(){$.mobile.changepage("test.html");})
then, my device will redirect to test.html which seem to be
$("#btnTest").click(function(){alert("123");})
<button id="btnTest">Test</button>
However, the script will never execute in test.html. Then I put the script to index.html, what I expect to be is done. Whatever, if I put all the script to the same page, the project will become harder and harder to be preserved. Appreciated for your help.
Intro
This article can also be found HERE as a part of my blog.
How jQuery Mobile handles page changes
To understand this situation you need to understand how jQuery Mobile works. It uses ajax to load other pages.
First page is loaded normally. Its HEAD and BODY is loaded into the DOM, and they are there to await other content. When second page is loaded, only its BODY content is loaded into the DOM. To be more precise, even BODY is not fully loaded. Only first div with an attribute data-role="page" will be loaded, everything else is going to be discarded. Even if you have more pages inside a BODY only first one is going to be loaded. This rule only applies to subsequent pages, if you have more pages in an initial HTML all of them will be loaded.
That's why your button is show successfully but click event is not working. Same click event whose parent HEAD was disregarded during the page transition.
Here's an official documentation: http://jquerymobile.com/demos/1.2.0/docs/pages/page-links.html
Unfortunately you are not going to find this described in their documentation. Ether they think this is a common knowledge or they forgot to describe this like my other topics. (jQuery Mobile documentation is big but lacking many things).
Solution 1
In your second page, and every other page, move your SCRIPT tag into the BODY content, like this:
<body>
<div data-role="page">
// And rest of your HTML content
<script>
// Your javascript will go here
</script>
</div>
</body>
This is a quick solution but still an ugly one.
Working example can be found in my other answer here: Pageshow not triggered after changepage
Another working example: Page loaded differently with jQuery-mobile transition
Solution 2
Move all of your javascript into the original first HTML. Collect everything and put it inside a single js file, into a HEAD. Initialize it after jQuery Mobile has been loaded.
<head>
<meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; minimum-scale=1.0; user-scalable=no; target-densityDpi=device-dpi"/>
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.2.0/jquery.mobile-1.2.0.min.css" />
<script src="http://code.jquery.com/mobile/1.2.0/jquery.mobile-1.2.0.min.js"></script>
<script src="index.js"></script> // Put your code into a new file
</head>
In the end I will describe why this is a part of a good solution.
Solution 3
Use rel="external" in your buttons and every elements you are using to change page. Because of it ajax is not going to be used for page loading and your jQuery Mobile app will behave like a normal web application. Unfortunately this is not a good solution in your case. Phonegap should never work as a normal web app.
Next
Official documentation, look for a chapter: Linking without Ajax
Realistic solution
Realistic solution would use Solution 2. But unlike solution 2, I would use that same index.js file and initialize it inside a HEAD of every possible other page.
Now you can ask me WHY?
Phonegap like jQuery Mobile is buggy, and sooner or later there's going to be an error and your app will fail (including loaded DOM) if your every js content is inside a single HTML file. DOM could be erased and Phonegap will refresh your current page. If that page don't have javascript that it will not work until it is restarted.
Final words
This problem can be easily fixed with a good page architecture. If anyone is interested I have wrote an ARTICLE about good jQuery Mobile page architecture. In a nut shell I am discussing that knowledge of how jQuery Mobile works is the most important thing you need to know before you can successfully create you first app.
Unlike normal ordinary HTML pages, jQuery Mobile uses ajax technology when navigating between pages. So make sure to import all your JS files and libraries in all your html pages.
If you notice closely you will see that JS files from previous page is taken into consideration when loading the second page. But if you force rrefresh the current page then the js files of the current page will be effective.
So as I said earlier make sure to import the js files in all the html files.
Also no need to call deviceready, use following syntax to call your page specific js functions
$(document).on('pageshow', '#YourPageID', function(){
// Your code goes here
});
Jquery Mobile uses ajax to load a "page". A "page" here is a div with data-role=page. If you load a physical page index.html, you can navigate using changePage to any "page" div inside that page.
However, if you want to load a "page" from other physical page, jQM will only load the first "page" div from that page. What actually happen is you do not change page, jQM just load that particular "page" div using ajax and inject it to your current page.
You have two possible architecture where you put all your "pages" in a html page and navigate from there. Or you can have multiple page architecture. You can always mix this.
To physically change page, you need to add rel=external to your link.

Countdown timer with ajax loaded content (jquery mobile) not working

I am having some trouble getting a countdown timer to work on my jQuery mobile page. If I have it load on a static html page it works as it should (see that page here:http://www.beingproperties.com/match-game). when you hit the start game the timer starts.
I have recently ported this over to the jQuery mobile framework and the timer is not working on that site (see this here by going to the link and clicking the 'multi-page link, then the start game link): http://www.beingproperties.com/match-game/home.html).
I have tied using 'pageshow' as scene below and though I get it to work and throw an alert, once I add in my code to execute nothing happens.
$('#shapesPage').live('pageshow', function () {
I know that it's something regarding the ajax loaded page, though all other jQuery fires on this page except for the countdown timer. I'm at a loss and would much appreciate a kick in the right direction.
I used the inspector and it's not very informative. Any insight to get this resolved, or proper ways to debug these types of issues would be much appreciated. thanks in advance. -Chris
Looking at the source for home.html, it seems that you haven't included js/plugins.js, only js/index.js.
I know you've included it in shapes.html, but JQM is a bit weird about loading external scripts when loading a page via ajax, as stated in the documentation:
The simplest approach when building a jQuery Mobile site is to reference the same set of stylesheets and scripts in the head of every page. If you need to load in specific scripts or styles for a particular page, we recommend binding logic to the pageinit event (details below) to run necessary code when a specific page is created (which can be determined by its id attribute, or a number of other ways). Following this approach will ensure that the code executes if the page is loaded directly or is pulled in and shown via Ajax.
Edit: You can not call any functions that modify the DOM until it is fully loaded. This is signaled in JQM by the pageinit event. Read about scripting and events for more info.
Try surrounding your javascript for shapes.html with
$( document ).delegate("#shapesPage", "pageinit", function() {
...
});

Dynamic content with JavaScript which allows linking

Let's say I want to create a website that contains one page. All the content is dynamic and generated using JavaScript with DOM replacement. The good thing about this is that it creates a better user experience, especially for applications that contain catalogues (online stores, galleries, etc). The problem now comes with linking. Let's say I'm browsing the site and I feel like sharing that particular thing I'm looking at with someone, but the problem is the link is always the same since it's JavaScript that's doing the magic. So the question comes: how can I create a fully JavaScript run website while maintaining the ability to link?
Now there's hash linking, but I'm failing miserably. I've tried overriding all <a> tags, changing the hash, and preventing the default action like so
$("a").click( function(){
window.location.hash = $(this).attr("id");
processHash();
return false;
});
Yet, it will randomly scroll my body for no reason.
I'd like some insights on the restrictions of linking in a fully dynamic website. Thanks.
Here is one simple thing you can do:
window.onload = function () {
processHash();
}
or it can be using jquery $(function () {...});
what happens here is when the page is loaded example http://www.example.com/#some-link
the page content is loaded first then your function that handle links processHash(); will do its work
not even the new and shiny jQuery mobile library is 100% ajax, but it's close. Obviously with a very modern browser, checkout this doc site done in jQuery mobile: http://jquerymobile.com/test/
If you dig in the docs a little you see how they use hash linking with the framework and html5 data-content="page"
each <div data-content="page">Is an independent page, if I remember right</div>

Load web pages with AJAX

Is it possible to load full web pages with AJAX and how would I go about it?
I'm thinking that I can create individual pages as I normally would, and then use AJAX somehow to get that page, and present it where the user currently is. Is that the correct assumption to make?
Basically I'm aiming to make a more dynamic site, so when the user clicks an option it will scroll down and reveal the requested info, without a noticeable page redirect.
Any advice would be great.
Thanks.
Jquery's .load(url) method loads HTML direct into an element. So if you changed every <a> tag to be a .load() on your top-level element you could do this. It would be a bit like using frames, but targeting a DIV instead of a frame.
Of course it would break lots of things like the back-button, form handling etc etc unless you put a lot of work in.
So, like the doctor who when told "It hurts when I do this" replied "well don't do that then", the answer is probably "dont do that".
One possible way is to fetch the HTML and then write it into a div
Yes it is possible. You could create a page/site from pure JavaScript fetching all elements from a web service or similar handler. It's a nightmare to maintain though, and you run into all sorts of problems depending on your needs. I did it as an exercise in learning jQuery, AJAX and a few other things. I found form submissions became tricky. While the data is posted to a web service with AJAX, managing the state of the page became very convoluted, and it only got nightmarish as the needs of the site grew.
I also found that in order to accomplish this, you have to make a choice to refresh the entire interface during transitions or just the section being changed. Refreshing the entire interface is cumbersome and for "rapid" users, the AJAX may not be able to keep up. It also causes collisions on the web service requests. If your page has 4 separate sections being updated, it is not uncommon for a web service request to be "lost" in the middle leaving a section without an update.
So the answer to your question is "yes". Reading your question closely, I would keep the scope of your requests to individual display pages without much functionality. The simpler you keep it, the easier it is to maintain and use.
I know this is an old post but this is a nice little script that can do the job. It can add ajax content loading to a existing non ajax site. Requires jQuery.
Script
<script type="text/javascript">
//Your navigation bar, can be "document" or body
var $navigation = $(".side");
//Your main content that will be replaces
var body = ".page";
var $body = $(body);
$navigation.delegate("a", "click", function() {
window.location.hash = $(this).attr("href");
return false;
});
$(window).bind('hashchange', function() {
var newHash = window.location.hash.substring(1);
if(newHash) {
$body.fadeOut(200, function() {
$body.hide().load(newHash + " " + body, function() {
$body.fadeIn(200, function() {
});
});
});
};
});
$(window).trigger('hashchange');
</script>
Details
All the links under $navigation will have a click event added to them that will update the window url hash. The window is listening for the hash change and will use the hash value to make an AJAX request to reload the $body html.
Advantage
History (Back & Forward) navigation will work:
The same site will work with browsers that support JavaScript and browsers that don't;
If you copy past the url the script will load the correct page;
Because we are using the delegate function any links that are added via the result of the ajax load will also have the click event added to them
Disadvantage
You can no longer use anchors on your site
For more information and a example see: http://css-tricks.com/video-screencasts/85-best-practices-dynamic-content/

Categories