jQuery Mobile 脚本加载问题
刚开始使用jQuery Mobile,发现很多问题需要重新考虑,比如脚本加载问题。
在普通html中,如果a.html中有链接到b.html,b.html中有类似代码:
$(document).ready(function() {
            alert("hello");
        });
则这段代码可以被正常执行。
而在jQuery Mobile中,这样做就行不通了,在浏览器中直接刷新b.html,则代码可以正常执行,而从a.html跳转到b.html时则不会被执行!为什么?
参见:
http://www.cnblogs.com/pinocchioatbeijing/archive/2013/12/08/3463857.html
第一次做用jQuery Mobile做东西,发现一些跟平时的思维习惯不太一样的。其中这个框架的页面加载机制便是其中一个。如果不明白其中的奥秘,往往会出现一些让人摸不着头脑的怪现象,比如页面进入后点击按钮后Javascript就是不执行,而用F5刷新页面后又可以正常执行等。
即使我们明白了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会被加载进去,其余的东西则无缘进入页面渲染。
直接上代码,或许更容易让人明白些:
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"/>    <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 articlewhere 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">
.......
jQuery Mobile 脚本加载问题的更多相关文章
- JQuery Mobile - 处理图片加载失败!
		
重点来了:一定要记住error事件不冒泡(如果要用js的方法替换默认出错图片,记得把img的alt属性去掉). 相关的知识点:jquery的ready方法.$("img").err ...
 - JQuery Mobile页面加载处理
		
在弄移动Web时采用了JQueryMobile框架. 奇怪的是 在使用页面加载 时 事件无效 我尝试了两种方法: $(document).ready(function(){ //do events } ...
 - jquery mobile动态加载数据后无法渲染
		
引自:http://blog.sina.com.cn/s/blog_025270e901016lst.html jquery mobile在动态添加html之后无法渲染控件,无法转换控件的办法! jq ...
 - jquery mobile 动态加载标签时,无法正常展示样式
		
原因 在chrome中审查元素,发现其增加了很多没有直接写在页面上的标签和样式.页面标签首先经过jquery.mobile-1.4.5.min.js的处理,添加了许多标签,然后再用css布局 解决方案 ...
 - jQuery实现DOM加载方法源码分析
		
传统的判断dom加载的方法 使用 dom0级 onload事件来进行触发所有浏览器都支持在最初是很流行的写法 我们都熟悉这种写法: window.onload=function(){ ... } 但 ...
 - 你不知道的JavaScript--Item26  异步的脚本加载
		
先来看这行代码: <script src = "allMyClientSideCode.js"></script> 这有点儿--不怎么样."这该放 ...
 - 浏览器环境下Javascript脚本加载与执行探析之DOMContentLoaded
		
在”浏览器环境下Javascript脚本加载与执行探析“系列文章的前几篇,分别针对浏览器环境下JavaScript加载与执行相关的知识点或者属性进行了探究,感兴趣的同学可以先行阅读前几篇文章,了解相关 ...
 - 浏览器环境下JavaScript脚本加载与执行探析之动态脚本与Ajax脚本注入
		
在<浏览器环境下JavaScript脚本加载与执行探析之defer与async特性>中,我们研究了延迟脚本(defer)和异步脚本(async)的执行时机.浏览器支持情况.浏览器bug以及 ...
 - 浏览器环境下JavaScript脚本加载与执行探析之defer与async特性
		
defer和async特性相信是很多JavaScript开发者"熟悉而又不熟悉"的两个特性,从字面上来看,二者的功能很好理解,分别是"延迟脚本"和"异 ...
 
随机推荐
- CentOS 基本设置
			
CentOS 基本设置 1.更改163源 在使用yum的时候,可能yum被锁,可用如下命令解锁:rm -rf /var/run/yum.id 2.编译安装开源软件 安装自己编译的开源软件一般都会在/u ...
 - An internal error occured during :"C/C++" . java.lang.NullPointerException
			
用eclipse 导入cocos2d项目的时候报了这个错,导致项目在eclipse 里面是空的,反复导入也不行. 解决办法,把其他正常项目里面的proj.android目录下面的.cproject文件 ...
 - 黑马程序员——JAVA基础之反射
			
------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- Java 反射是Java语言的一个很重要的特征,它使得Java具体了"动态 ...
 - Spring源码学习之:@async  方法上添加该注解实现异步调用的原理
			
在我们使用spring框架的过程中,在很多时候我们会使用@async注解来异步执行某一些方法,提高系统的执行效率.今天我们来探讨下 spring 是如何完成这个功能的. spring 在扫描be ...
 - 源码分析:Java对象的内存分配
			
Java对象的分配,根据其过程,将其分为快速分配和慢速分配两种形式,其中快速分配使用无锁的指针碰撞技术在新生代的Eden区上进行分配,而慢速分配根据堆的实现方式.GC的实现方式.代的实现方式不同而具有 ...
 - Python学习笔记——文件操作
			
python中,一切皆对象. 一.文件操作流程 (1)打开文件,得到一个文件句柄(对象),赋给一个对象: (2)通过文件句柄对文件进行操作: (3)关闭文件. 文件对象f通过open()函数来创建 ...
 - Spring4.1.6 标签注解大全以及解释
			
常用的spring注解有如下几种: @Controller@Service@Autowired@RequestMapping@RequestParam@ModelAttribute@Cacheable ...
 - Openstack Neutron DVR workflow
			
目前在Juno版本的trunk中已经合入了DVR相关的代码,我的理解是在Juno版本中DVR是一个experimental feature.最好需要稳定一个版本以后再上生产环境.之前写过一篇博文是DV ...
 - 操作系统中前台进程与后台进程(适用于Linux)
			
两种进程的主要区别: 1.前台进程用户可以操作,后台进程用户不能操作(除了把它关闭). 2.前台进程不全是由计算机自动控制,后台进程全都是由计算机自动控制. 3.后台进程一般用作系统服务,可以用cro ...
 - [转载] 【Shiro】Apache Shiro架构之实际运用(整合到Spring中)
			
写在前面:前面陆陆续续对Shiro的使用做了一些总结,如题,这篇博文主要是总结一下如何将Shiro运用到实际项目中,也就是将Shiro整到Spring中进行开发.后来想想既然要整,就索性把Spring ...