剛開始使用jQuery Mobile,發現不少問題須要從新考慮,好比腳本加載問題。javascript
在普通html中,若是a.html中有連接到b.html,b.html中有相似代碼:css
$(document).ready(function() {
alert("hello");
});html
則這段代碼能夠被正常執行。java
而在jQuery Mobile中,這樣作就行不通了,在瀏覽器中直接刷新b.html,則代碼能夠正常執行,而從a.html跳轉到b.html時則不會被執行!爲何?jquery
參見:web
http://www.cnblogs.com/pinocchioatbeijing/archive/2013/12/08/3463857.html瀏覽器
第一次作用jQuery Mobile作東西,發現一些跟平時的思惟習慣不太同樣的。其中這個框架的頁面加載機制即是其中一個。若是不明白其中的奧祕,每每會出現一些讓人摸不着頭腦的怪現象,好比頁面進入後點擊按鈕後Javascript就是不執行,而用F5刷新頁面後又能夠正常執行等。app
即便咱們明白了HTML文件與jQuery Mobile中page概念的區別,也仍是不能解決上述問題。固然,瞭解這個是一個大前提。原來,jQuery Mobile是用Ajax的方式加載全部HTML中的標記data-role="page"的DIV元素中,第一個HTML頁面通常都是徹底加載,包括 HEAD
和
BODY
都會被加載到DOM
中,完成後即是連接到的其餘頁面內容的加載。 第二個HTML頁面只有 BODY
中的內容會被以Ajax的方式加載到頭一個HTML的 DOM中。
而且第二HTML頁面的 BODY
中的內容也並不是所有加載,而僅僅是其中的第一個帶data-role="page"屬性的DIV會被加載進去,其他的東西則無緣進入頁面渲染。cors
直接上代碼,或許更容易讓人明白些:框架
<!DOCTYPE html> <html lang="en"> <head> <!-- META TAGS Declaration --> <meta charset="UTF-8"> <title>TEst</title> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0;" /> <meta name="apple-mobile-web-app-capable" content="yes" /> <link rel="stylesheet" href="http://code.jquery.com/mobile/1.3.1/jquery.mobile-1.3.1.min.css" /> <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> <script> $(document).on('pagebeforeshow', '#foo', function(){ alert($('#body-test').html()); }); </script> </head> <body id="body-test"> <div data-role="page" id="portfolio" data-add-back-btn="true"> <div data-role="content" data-theme='c' > <a href="test.html" data-role="button">Go to Bar</a> </div> </div><!-- Page Project #1 --> </body> </html>
<html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="style/jquery.mobile-1.3.1.css" /> <script src="jquery-js/jquery-1.10.1.js"></script> <script src="jquery-js/jquery.mobile-1.3.1.js"></script> <title>Foobar</title> </head> <body> <div data-role="page" id="foo"> <div data-role="content"> <a href="#bar" data-role="button">Go to Bar</a> </div> </div> <div data-role="page" id="bar"> <div data-role="content"> <p>Bar</p> </div> </div> </body> </html>
好了,再看這篇文章:
http://stackoverflow.com/questions/17403825/link-fails-to-work-unless-refreshing/17403907
他還有另一篇文章:
http://www.gajotres.net/how-jquery-mobile-page-handling-affects-javascript-executions/
For us to understand this situation we need to understand how jQuery Mobile works. It uses Ajax for page loading into the DOM.
First page is loaded normally. Its HEAD and BODY is loaded into the DOM. That content will stay there (unless page is refreshed) to await further content loading. When second page is loaded, only its BODY content is loaded into the DOM, and when I say its BODY content I mean DIV with an attribute data-role=」page」 and its inner content.
This may not sound like something problematic, but you should think twice. What if we have several HTML pages and every and each page has something unique, let’s say different javascript intended to be used only during that page execution, not to mention additional CSS files. Everything found in a HEAD of those files are going to be discarded, and its javascript is not going to be executed.
Unfortunately, you are not going to find this described in their documentation. This is either thought to be a common knowledge or they just forgot to mention it.
There are several solutions to this problem; some are good and some are bad, everything should depend on a project architecture.
This article is an response to my Stackoveflow answer that can be found here.
In your second page and every other page, move your SCRIPT tag into the BODY content, like this:
1
2
3
4
5
6
7
8
|
<
body
>
<
div
data-role
=
"page"
>
<
script
>
// Your javascript will go here
</
script
>
// And rest of your HTML content
<
div
>
</
body
>
|
This is a quick solution but 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
Move all of your javascript into the original first HTML. Collect everything and put it into a single js file, into a HEAD. Initialize it after jQuery Mobile has been loaded.
1
2
3
4
5
6
|
<
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
=
"index.js"
></
script
> // Put your code into a new file
</
head
>
|
At the end of this article, I will describe why this is a good solution.
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 regular web application. Unfortunately, this is not that good solution. If Ajax is not used for page loading, you will loose a lot of functionalities that make jQuery Mobile such a great framework.
1
|
<
a
href
=
"#second"
class
=
"ui-btn-right"
rel
=
"external"
>Next</
a
>
|
Official documentation, look for a chapter: Linking without Ajax.
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 may ask WHY is that?
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 js content is inside a single HTML file. DOM could be erased, and browser or you will refresh your current page. If that current HTML page don’t have javascript initialized inside its HEAD then that web app will not work until everything is restarted.
In the end, when creating a jQuery Mobile application spend some time thinking about a page architecture. If you need a help take a look at my other article where I am discussing secrets of a good jQuery Mobile architecture.
好吧,最後總結一下:
若是多個html,請將第二個頁面的腳本放在第一個page後面,緊跟在page後面,像這樣:
<body> <div data-role="page"> <script type="text/javascript"> $.support.cors =true; $.mobile.allowCrossDomainPages=true; $(document).ready(function() { alert("hello"); }); </script> <div data-role="header" data-position="fixed"> .......