On a particular page, I am using jquery ui tab to tabify my web page. My JavaScripts are placed in external files and loaded at the end of my HTML. On document ready event, the very first thing I do is to call the tabify plugin.
The problem is that the browser has already painted the page at this point, then repaints it once it tabifies the page. So, I get a split-second flickering of the screen. How do I prevent this flickering? I do not want to load JavaScripts in as I am trying to optimize my site per Google PageSpeed/Yahoo YSlow recommendations.
<html>
<body>
....
<script src="tabify.js"></script>
</body>
</html>
tabify.js
$('document').ready(function(){
$("#tabs").tabs();
});
hide the content with css display:none; then use $("#tabs").show().tabs();
Related
I have two very simple pages as below. If I browse to "mysite.com/" the webserver returns the "index.html" content, as is normal. If I then click the "page2" link, jquery mobile loads the 2nd page into the DOM, but doesn't unload the first page from the DOM, although it is hidden (display:none) from view.
I now have 2 <div data-role="page"> elements in the DOM, with only page2 page visible on screen. If I then click the "index" link on page2, jquery mobile unloads page2 from the DOM, and loads the index.html page into a new DOM element. I now have two instances of <div id="index"> in the DOM which is obviously incorrect!
What is going on? I thought I'd ask on here before reporting it as a bug but it seems like a very simple example that is completely broken!
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.css" />
<script src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
<script src="http://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.js"></script>
</head>
<body>
<div data-role="page" id="index">
Page2
<p>index page</p>
</div>
</body>
</html>
page2.html
<html>
<body>
<div data-role="page" id="page-2">
Index
<p>Page 2</p>
</div>
</body>
</html>
EDIT:
I found a workaround of page2.html linking to rather than "index.html", which prevents the 2nd duplicate loading, but it still seems wrong that the original page loaded is always kept in the DOM.
EDIT 2: This is a known issue https://github.com/jquery/jquery-mobile/issues/4050 - I just didn't manage to find it despite extensive googling before posting this question. I might raise a bug report against their documentation though, because it is highly unexpected behaviour IMO.
This is the default behavior of jQuery Mobile, first landing page is always kept in DOM. It only removes external pages which aren't cached data-dom-cache="true". You will always have two pages in DOM, landing page and active external page.
Nevertheless, if you wish to remove landing page once you navigate to another page, add data-external-page="true" to page div of the landing page. Once it's created pagecreate, flag it for removal .page("bindRemove"). This is the way jQuery Mobile removes external pages.
Note that is fix will work as long as .page() widget isn't removed and replaced by .pagecontainer() widget.
<div data-role="page" id="pageID" data-external-page="true">
$(document).on("pagecreate", "#pageID", function (e) {
$(e.target).page("bindRemove");
});
Demo
I created a test as described in your question with the two files index.html and page2.html and tested with Chrome (version 38.0). I loaded index.html and then navigated to page2.html and then back to index.html. Using Chrome Developer Tools, I then examined the elements in the page and found the following (screen shot):
As we see, there is one instance of the page called index and one instance of the page called page-2 but no duplicates.
I realize that this does not line up with your own results but am offering this is an answer demonstrating that the story works as expected. If we determine a flaw in the logic of this answer, I'll happily delete it.
I have some jquery mobile pages with custom css but it takes only effect when i reload the page and not at first load.
The css file is called in all sites with:
<link rel="stylesheet" href="http://mobile.kerger-mg.de/rezepte-suche/stylesheet/style.css" />
Thanks in advance for any suggestions and your time.
You must load all css the first time, in other words all pages must have the same inclusions,
don't forget that jqm is based on ajax navigation...
try to link the page in question in this way:
<a href="PAGE_WITH_PROBLEM_CSS.html" rel="external">
in this way, the landing page (PAGE_WITH_PROBLEM_CSS.html) is reloaded.
:)
I have this index.html and login.html and I use a href to link from index to login. and in each index.html and login.html I import the javascript. However, it seems that only the ones come from index.html that is being loaded. so if I place the js in index.html for the login.html, it works fine. but then, we I place it separately ( another js for login.html that is not in index.html) , it doesnt work
TIA
When JQM(jQuery mobile) loads a page it uses ajax to accomplish this. When this happens all code in the <head> section is ignored. JQM looks for the data-role="page" part and inserts it into the same dom as index.html. So basically you are doing it the correct way when you add your js in the index.html page.
If you would like to compartmentalize your js code to work for certain pages use this example:
$(document).on('pageinit', '#page1', function(){
// code for #page1
});
$(document).on('pageinit', '#page2', function(){
// code for #page2
});
$(document).on('pageinit', '[data-role=page]', function(){
// this code will execute for every page that is data-role="page"
});
So go ahead and put all your code in one file. Split your code into appropriate pages like above and include that in your index.html file.
Also if you are using JQM version 1.0.1 with jQuery version 1.6.4(recommended with 1.0.1) use .delegate() instead of .on(). i.e.
$(document).delegate('#page1', 'pageinit', function(){ // notice that pageinit and #page1 are switched around for delegate
// code for #page1
}); // interesting to note that if you use delegate in jQuery 1.7.x it actually just calls the .on() method.
Note If you were making a web application instead of a phonegap app you would be smart to put your javascript in that one file and include that in every page. This way if someone is following a link or bookmarked your page they will still get the correct javascript file they need.
Anyways I hope that helps you out. Good luck!
If you are doing a window.location.href then it will load the new HTML(In you case it is login.html) If you are using this approach then you have to reload all you scripts again and hence add these scripts in all your .html pages.
<script src="cordova-1.6.0.js" type="text/javascript"></script>
<script type="text/javascript" src="jquery/jquery-1.7.1.min.js"></script>
<link rel="stylesheet" href="jquerymobile/jquery.mobile-1.1.0.min.css" />
<script type="text/javascript" src="jquerymobile/jquery.mobile-1.1.0.min.js"></script>
However if you use the approach recommended by #deadlock then you will just need to load the script once. The later approach is the best one.
Please post your code, specifically how the pages link to each other, and the global config settings you set for app, if any. Like much with jQM, there are multiple practices and strategies supported for page arch.
You can also learn by using desktop browser tools and view the "Resources" to see what and when your resources are being loaded.
I have this:
<title>MyMobile</title>
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.0/jquery.mobile-1.0.min.css" />
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript" src="http://code.jquery.com/mobile/1.0/jquery.mobile-1.0.min.js"></script>
<title>My Mobile</title>
<style type="text/css">
table { width:100%; }
table caption { text-align:left; }
table thead th { text-align:left; border-bottom-width:1px; border-top-width:1px; }
table th, td { text-align:left; padding:6px;border: inset 1pt}
</style>
If I go to the page manually my table elements look fine. I can see the borders, etc. If I got the page from another mobile page the page loads ok but the table CSS stuff never get applied. No styles. Hit referesh, styled.
What is going on?
Thank you.
edit: not loading my javascript either. refresh. all works again.
edit: does same if I hit the back button to another page. not everything loads.
Whenever you have A tags, JQM by default uses AJAX to load those pages - and then ignores everything but whatever is included inside the div data-role=page element.
You have 3 options:
You can either tell JQM to always disable AJAX (by setting ajaxEnabled to false) and load pages as "normal browsers" do - this will re-load also all javascript includes, stylesheets, etc...
You can include all the different div data-role=page inside ONE .html page, that way JQM will need to load nothing else when navigating between pages
You can still use AJAX and load external files, but then you'll need to include all your code (HTML/CSS/JS) INSIDE the DIV itself. Note that at this option you'll need to attach to different events (pageinit/beforeshow/show/hide) and not $.ready (since JQM will then take care of that and the DOMContentReady is not actually going to fire.
You can read all about this in the documentation
Hope this helps...
I want to open the the .html file from my .js file. So I Used the $.mobile.changePage("file.html"). In the file.html have file.js. But The file.js does not call when the file.html in invoked.
THanks in advance.
first.js
$.mobile.changePage ("file.html");
file.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>jQuery Mobile Framework - Dialog Example</title>
<link rel="stylesheet" href="jquery.mobile-1.0a2.min.css" />
<script src="jquery-1.4.4.min.js"></script>
<script src="jquery.mobile-1.0a2.min.js"></script>
<script src="../Scripts/file.js"/> // Could not imported
<script src="../Scripts/helperArrays.js"/> // Could not imported
<script src="../Scripts/globalVariables.js"/> // Could not imported
</head>
<body>
<div data-role="page">
<div data-role="header" data-nobackbtn="true">
<h1>Vaults</h1>
</div>
<!-- <div data-role="content" data-theme="c" id="contentVault">
Sample Vault
My Vault
</div> -->
<div data-role="content" id="content">
<ul id="listview" data-role="listview" data-inset="true" data-theme="e" data-dividertheme="b">
<li id="listdiv" data-role="list-divider">List of Items</li>
</ul>
</div><!-- /content -->
</div>
</body>
</html>
Please help me..
When jQM loads another page through AJAX it only pulls in anything within your div[data-role="page"] and nothing else, like the head
So you can if you wanted to, include any JS/CSS within this div, the problem is that if this page is accessed multiple times any CSS will accumulate, but the problem is much worse for JS.
You are basically getting every page appended to the DOM, so the JS runs on the entire DOM (every page you loaded) if you use a global selector like $('div.someClass'), even using an ID isn't a perfect solution because if you can link to the same page twice.
For Smaller Sites
I've solved this by moving all the CSS into one file and for JS code that I want to run each time the page is loaded, I bind to the pageinit and pageshow jQM events:
<script type="text/javascript">
$("div:jqmData(role='page'):last").bind('pageinit', function(){
//your code here - $.mobile.activePage not declared
});
$("div:jqmData(role='page'):last").bind('pageshow', function(){
//your code here - $.mobile.activePage works now
});
</script>
The pageinit event runs when the page is loaded, only ever once (after it's loaded it stays in memory if you navigate back to it, even via a back button this isn't fired again), pageshow on the other hand fires everytime the page is shown, even when you navigate back to it via the back button on the browser for example.
The pageinit runs when the DOM is there, the pageshow event is only if you have some code that depends on the DOM being rendered and you need a quick reference to the active page through $.mobile.activePage or some data changed and you need to refresh this back everytime it's shown. For most purposes I only use the pageinit as a document.ready for jQM and bind my events there. Use bind for static elements, and on instead of live for dynamic elements, because live events listen at the document root, you want to listen at the page div.
For Larger Sites
For larger sites there are advantages to binding a live event to any pages and handling types of pages, this way js code isn't loaded more than once.
If you have external js files with say helper functions that you only need once put that in the head of all your pages (if there aren't too many), if you had a very big site you could probably do better by tracking which JS files have been loaded server side.
All this can be avoided by just not using AJAX to load new pages, so think about whether that transition/loading effect is worthwhile
*Here's how I handle large jQM sites: *
bind a live event to all pages/dialogs pageinit and pageshow events:
$(document).on('pageinit pageshow', 'div:jqmData(role="page"), div:jqmData(role="dialog")', function(event){
I reference each page with a name: <div data-role="page" data-mypage="employeelist">
In this live event you can basically have a switch statement for each page "name", and then check event.type for pageinit/pageshow or both and put your code there, then every time a page is created/shown this event will be fired, it knows what page triggered it and then calls the corresponding code
I eventually had too much code, so I built a handler object where each page's js is included in a separate js file and can register handlers with the live event
The drawback is that all your js for your entire site is loaded on the first page the user reaches, but minified even a large site is smaller than jQuery or jQM so this shouldn't be a concern. The advantage is you are no longer loading all your JS for each page through AJAX each time the user navigates to a new page.
*note: now RequireJS can make this even more manageable
Jquery mobile gets pages via AJAX and adds their content to the current page.
I saw some notices about changing the page title to the incoming one, so they are (planning?) accessing the head, but at the moment jquery mobile doesn't seem to load external js when loadin a page.
More importantly - if you use $(document).ready() it will not be triggered, because it was AJAX