jQuery Mobile 脚本加载问题

刚开始使用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

直接上代码,或许更容易让人明白些:框架

index.html

<!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>

 

test.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/

 

How jQuery Mobile page handling affects javascript execution

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.

 

Intro

 

This article is an response to my Stackoveflow answer that can be found here.

 

Solution 1

 

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

 

Solution 2

 

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 = "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 >
 

At the end of this article, I will describe why this is 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 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

 

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">


.......
相关文章
相关标签/搜索