I am developing an application by using phonegap and jQuery Mobile. Phonegap recommends a single document structure. As 5 divs or more in a document are pretty unclear, I'm trying to split up my pages (the div's) into multiple documents. As soon as phonegap loads the app, I want to insert these documents into the index.html.
function loadPage(external_document) {
var docname=external_document+".html";
$.get(docname, function(data) {
console.log(docname+" loading");
$("body").append($(data).find("body"));
$("head").append($(data).find("head"));
console.log(docname+" loaded");
});
}
document.addEventListener("deviceready", function(){
loadPage("DialogCredentials");
}, false);
DialogCredentials.html
<html>
<head>
<script type="text/javascript" src="js/DialogCredentials.js"></script>
</head>
<body>
<div data-role="page" id="dlg_credentials">
<div data-role="header"><h1>Login</h1></div>
<div data-role="content">
...
</div>
</div><!-- /page -->
</body>
</html>
As soon as the loadPage gets executed there should be a <div id="dlg_credentials"… and the corresponding javascript tag in the dom of my main document. But it isn't. There are no errors shown in the web inspector.
So what am I doing wrong here?
Without setting up a test case for you, if you really want to separate your pages to make your coding easier I would recommend to load the pages the standard way for jQuery Mobile i.e.
$.mobile.changePage( "about/us.html", { transition: "slideup"} );
This way you aren't reinventing the wheel and it satisfies your request. The overhead will be negligible compared to your proposed solution in any case let alone taking into account you want the first page to render quickly rather than to be blocked by inserting many pages before any html is rendered in any case. Since they will be local on the device in any case Phonegap will be able to serve them very quickly.
One thing to remember when loading pages through jQuery Mobile is that it strips out anything in the target page outside of the
data-role="page|dialog|popup"
tag and therefore to load custom page-specific javascript I would recommend you include the script tag directly below the
data-role="page"
opening tag and set any page initialization to occur on "pageinit"
<div data-role="page" id="options" data-theme="a">
<script type="text/javascript">
$(document).bind('pageinit', initializeOptions());
function initializeOptions() {
// do your page initialization here . . .
}
</script>
<!-- rest of page continues here . . . . -->
and then continue with the rest of your page as needed. That way it will be parsed when the page is loaded via the $.mobile.changePage method.
Hope that helps.
Dynamic loading is a feature of several Javascript frameworks. AngularJS and Backbone.js for example. Maybe take a look at their approach to loading multiple views?
I have previously worked on an app that did this by adding an empty div for each view to the index.html, and then dynamically loading the Javascript for each view on demand. The Javascript for the views was responsible for rendering the HTML into the div for that view.
Related
Okay, so this one is gonna be a doozy!
NOTE: This will be for a windows desktop application running sqlite and mongoose, so loading times are not as important (to me, for now) and there will be no connection to a non-local server.
I have searched all over and couldn't find anything that is specific to my situation, most seem to load into an iframe or use that framework provided by css-tricks.com
I am using my own (sorta) framework. The libraries i am using are bootstrap 3, jquery 2.1.4, jqueryui 1.12.1, and Bootstrap-select v1.12.1
index.php will have all content dynamically loaded into a div#wrapper and will act as the head of all page loading. This is the skeleton of my index.php. In sidebar.html the links have the attribute 'pagetoload', jquery catches the click event and loads the data into div#wrapper
<body>
<?php require_once("res/sidebar.html"); ?>
<div class="container-fluid" id="body-container">
<div id="wrapper" style="border:1px black solid;">
<!-- dynamic page content will be loaded here-->
</div>
</div>
<script src="res/js/jquery.js"></script>
<script src="res/js/jquery-ui.js"></script>
<script src="res/js/bootstrap.js"></script>
<script src="res/js/bootstrap-select.js"></script>
<script src="res/js/menu-handling.js"></script>
<script>
//index.php js
$(document).ready(function () {
$.get("home.php", function (data) {
$("div#wrapper").html(data);
});
$("a.loader").click(function (e) {
e.preventDefault();
$.get($(this).attr("pagetoload"), function (data) {
$("div#wrapper").html(data);
});
});
//dateFormat 10/dd/yy to constrain input only to october
//get current month number and constrain to prevent additions to wrong month
$("#date-input").datepicker({
dateFormat: "12/dd/yy"
, constrainInput: true
});
$("#date-input").focus(function () {
$(this).datepicker("show");
});
});
</script>
</body>
Each page that will be dynamically loaded will ideally contain minimal php and only contain the necessary html/css/js for that page. My issue is for example, after loading one page such as my dbviewer.php (which contains js and gives me the asynchronous loading warning) and reloading home.php into the container, javascript no longer works. The javascript for each page are inline tags.
I have tried piling all the javascript for every dynamic page into index.php so that it's all loaded on startup, but the issue arises that it still won't work. What is the best method make this dynamic loading work while having each page modular. I have tried to researching this but only stuff like using the hashTag thing comes up.
If you need more code from my files please post, i think i explained it enough for you to understand as there is nothing too wild going on outside of index.php Just scripts inside each dynamic page that basically interacts with dom elements using jquery.
I'm leaving this answer because it helped you, and also can be usefull as a general rule of thumb for any developer out there that can find himself in similar situation.
So when developing the app you have to separate all javascript, css assets in master file to host them on first pageload. (maybe it's event better for performance)
All other server generated files (php, node.js etc) files you have do structure to only be data source for pages that users click or land to .. or at least try to..
after that you have to trigger
$.ajax().callback
function on frontend to do job on each page. Such as page effects, data manipulation and etc .. Callback is very important because that's when data was actually loaded!
cheers, k
I'm looking for a way to load jquery after the page is fully loaded.
well there are lots of questions and answers about it in here, but all describe how to run a script that needs jquery after either page or jquery fully loaded.
What I'm looking for is to load the page and then call jquery and after the jquery is loaded call the functions. something like:
document.onload=function(){
var fileref=document.createElement('script');
fileref.setAttribute("type","text/javascript");
fileref.setAttribute("src", 'http://code.jquery.com/jquery-1.7.2.min.js');
//Here I need an event to know that jquery is
//loaded to run stuff that needs jquery
}
Try this:
$(document).ready(function() {
// When the document is ready
// Do something
});
You can also use:
$(window).bind("load", function() {
// Your code here.
});
For your problem, the solution might be to attach CDN hosted by google with certain library:
https://developers.google.com/speed/libraries/devguide
Also, you can add this at the bottom of page (just before </body>):
<script type="text/javascript">
(function() {
var script = document.createElement('script')
script.setAttribute("type", "text/javascript")
script.setAttribute("src", "https://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js")
document.getElementsByTagName("head")[0].appendChild(script)
})();
</script>
However, this is risky in my opinion. You have an asynchronous call for jquery, thus your jquery has to wait until it loads (ie. $(document).ready won't work in this case). So my answer would be: use a CDN like google suggests; put your javascript on the bottom just before </body>; and, ignore flags from profilers.
It is advised to load your scripts at the bottom of your <body> block to speed up the page load, like this:
<body>
<!-- your content -->
<!-- your scripts -->
<script src=".."></script>
</body>
</html>
You can either use .onload function. It runs a function when the page is fully loaded including graphics.
window.onload=function(){
// Run code
};
Or another way is : Include scripts at the bottom of your page.
You can try using your function and using a timeout waiting until the jQuery object is loaded
Code:
document.onload=function(){
var fileref=document.createElement('script');
fileref.setAttribute("type","text/javascript");
fileref.setAttribute("src", 'http://code.jquery.com/jquery-1.7.2.min.js');
document.getElementsByTagName("head")[0].appendChild(fileref);
waitForjQuery();
}
function waitForjQuery() {
if (typeof jQuery != 'undefined') {
// do some stuff
} else {
window.setTimeout(function () { waitForjQuery(); }, 100);
}
}
My guess is that you load jQuery in the <head> section of your page. While this is not harmful, it slows down page load. Try using this pattern to speed up initial loading time of the DOM-Tree:
<!doctype html>
<html>
<head>
<title></title>
<meta charset="utf-8">
<!-- CSS -->
<link rel="stylesheet" type="text/css" href="">
</head>
<body>
<!-- PAGE CONTENT -->
<!-- JS -->
<script type="text/javascript" src="http://code.jquery.com/jquery-1.7.2.min.js"></script>
<script>
$(function() {
$('body').append('<p>I can happily use jQuery</p>');
});
</script>
</body>
</html>
Just add your scripts at the end of your <body>tag.
There are some scripts that need to be in the head due to practical reasons, the most prominent library being Modernizr
if you can load jQuery from your own server, then you can append this to your jQuery file:
jQuery(document).trigger('jquery.loaded');
then you can bind to that triggered event.
Include your scripts at the bottom of the page before closing body tag.
More info HERE.
If you're trying to avoid loading jquery until your content has been loaded, the best way is to simply put the reference to it in the bottom of your page, like many other answers have said.
General tips on Jquery usage:
Use a CDN. This way, your site can use the cached version a user likely has on their computer. The // at the beginning allows it to be called (and use the same resource) whether it's http or https. Example:
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
Using a CDN has a couple of big benefits: it makes it more likely that users have it cached from another site, so there will be no download (and no render-blocking). Further, CDNs use the closest, fastest connection available, meaning that if they do need to load it, it will probably be faster than connecting to your server. More info from Google.
Put scripts at the bottom. Move as much of your js to the bottom of the page as possible. I use php to include a file with all my JS resources below the footer.
If you're using a template system, you may need to have javascript spread throughout the html output. If you're using jquery in scripts that get called as the page renders, this will cause errors. To have your scripts wait until jquery is loaded, put them into
window.onload() = function () { //... your js that isn't called by user interaction ... }
This will prevent errors but still run before user interaction and without timers.
Of course, if jquery is cached, it won't matter too much where you put it, except to page speed tools that will tell you you're blocking rendering.
I have asked this question more than 6 years ago, and any answers I got had some flaws. Later I myself worked out a solution that I have been using for years since then. Now that I came across my own question again and I saw that it has many views, I'd like to share it because I think it may help others.
This problem mainly occurs on Master-Detail type of pages (can be old .master and .aspx pages) or (layout and views in asp.net) or any similar situation maybe on other web development languages, however always there is a master-detail pattern involved.
For the solution, I just add an array at the beginning of my page:
<script>var after = [];</script>
any function that requires jQuery or any other script that would run after this section, instead of running it, I just push it to this array:
after.push(function(){
// code that requires scripts that will load later,
//might be for example a jQuery selector or ...
});
and then at the very end of the page, right before closing the body tag (of course scripts are loaded by now) I run all the functions inside the (here named) after array:
<script>for(var i=0;i<after.length;i++)after[i]();</script>
</body>
I find this way very easy, simple and flawless.
I have some troubles with display charts (jquery Charts) into a web.
I have two pages (1.html and 2.html). The first contain a listview that links with the second page. The 2.html displays the chart. Here is the problem: When page 2 is launched through page 1, the chart doesn't appear!! But if I reload the page 2.. so the chart appears!
If I work with an only page using "href=#page" references the chart works fine and it's displayed, but my intention is to have different html files, one of them with the listview and the other one with the chart. Is it possible?
I have tested many types of jquery charts and all of them had the same behavior.
Any idea?
thanks for all,
Best Regards.
Here the files:
1.html ----
<head>
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.3.1/jquery.mobile-1.3.1.min.css" />
</head>
<body>
<div data-demo-html="true">
<ul data-role="listview" data-inset="true">
<li>Chart</li>
</ul>
</div>
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="http://code.jquery.com/mobile/1.3.1/jquery.mobile-1.3.1.min.js">/script>
</body>
2.html with the code into the reference (jqwidgets - chart_bar)
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.
The most realistic solution would be to 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. I would also 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.
I've listed other ways to fix this problem (with examples) in my answer here: Why I have to put all the script to index.html in jquery mobile.
On a jQuery page, I have a login form. The code is simple enough:
<form method="post">
<div data-role="fieldcontain">
.... Form here
</div>
</form>
but the following form is submitted, JQM loads the next page via Ajax POST.
The problem is that any in-line Javasctipt on that new page is NOT initialized. I'm not talking about the $(document) elements etc. the entire in-lined Javascript blocks aren't initialized.
However if I add
data-ajax="false"
to the form tag, everything is fine. The page is loaded and initialized correctly.
Why does this happen, and is there a way to trigger a page initialization with the ajax loaded content?
I've observed this on both Firefox and the Android Webview clients.
Reason data-ajax="false" worked in your case is because it will force a full page reload which will incidentally trigger page markup enhancement.
This is a segment from jQuery Mobile documentation:
It's important to note if you are linking from a mobile page that was
loaded via Ajax to a page that contains multiple internal pages, you
need to add a rel="external" or data-ajax="false" to the link. This
tells the framework to do a full page reload to clear out the Ajax
hash in the URL.
Now in your case if you want to enhance new page content use this:
$('#pageID').trigger('create');
or in case you have also made changes to header and footer use this:
$('#pageID').trigger('pagecreate');
If you want better understatement take a look at my blog ARTICLE, were I am talking about page content markup enhancement in great details. There you will find examples for functions mentioned on top. It can be also found HERE.
If you load your page with the default jQuery Mobile implementation (which utilizes ajax), only the script blocks on the first page (<div data-role="page">) will get loaded.
You can turn off ajax loading via mobileinit which will disable ajax loading globally or you can disable it via the source link.
$(document).on("mobileinit", function(){
$.mobile.ajaxEnabled = false;
});
or
<a data-role="button" data-ajax="false"
href="myPageWithItsOwnScriptBlock.html">Link</a>
If you want to continue using ajax loading, you can place the script block inside of you "page" <div>
<div data-role="page">
<script src="myscript.js"></script>
<div data-role="header">
....
Details here:
http://jquerymobile.com/demos/1.2.0/docs/pages/page-scripting.html
Try to encapsule your inline JS code into something like this:
$(document).bind('pageinit', function(event) {
// your inline code goes here
});
I am trying to compare having a 1 page app with clientside routing to having a asp mvc app which just routes to html files, to see which is more appropriate for my current project. As I have no need for any Asp Mvc features its all javascript/html which communicates with a web service.
However one problem I can forsee with the one page app is that my site isnt really 1 page, so I would be having to have on main index.html which contained all shared resources. Then dynamically load in new pages based on the hashbang and add in any required scripts and css. This doesn't seem to hard as Jquery I believe provides a .load() method or something similar to get external resources... my problem though is getting rid of them once I am done...
Is there any way to do this, so you target ONLY certain script/link tags, can you give them Ids or something?
Any help on this would be great...
== EDIT ==
Added a simple example to show what I mean:
<!-- Script already in page -->
<script type="text/javascript" src="scripts/script1.js"></script>
<!-- Dynamically added script -->
<script type="text/javascript">
// some javascript
</script>
How can you tell which ones you should remove? If you could apply an id or uniqueness to each script then it may be ok, but thats what i am getting at with this question.
There are zero benefits to "removing resources." When a script has been loaded, removing the script tag from the page later has no purpose--it won't improve your browser performance at all, nor will it harm it to keep the files around.
Simply add your resources as needed and write your code such that it won't execute erroneously.
I'm not shre i understand why you would like to do that but link element (for css) and script (for js) are elements like any other and they can be deleted with remove().