在多个页面使用同一个HTML片段《续》


Posted in Javascript onMarch 04, 2011

1. HTML页面:

<script type="text/javascript"> 
$(function() { 
$("#clickToInsert").click(function() { 
$.get("service.ashx?file=pages2_1.txt", function(data) { 
$("#placeholder").html(data); 
}, "text"); 
}); 
}); 
</script> 
<input type="button" id="clickToInsert" value="Insert HTML" /> 
<div id="placeholder"> 
</div>

2. service.ashx 后台代码:
public void ProcessRequest(HttpContext context) 
{ 
string filePath = context.Request["file"].ToString(); 
string fileContent = String.Empty; 
using (StreamReader sr = new StreamReader(context.Server.MapPath(filePath))) 
{ 
fileContent = sr.ReadToEnd(); 
} 
context.Response.ContentType = "text/plain"; 
context.Response.Write(fileContent); 
}

3. pages2_1.txt 文件:
<script type="text/javascript"> 
$(function() { 
var parent = $("#complex_page_segment"); 
$(".previous", parent).click(function() { 
$(".content", parent).html("Previous Page Content"); 
}); 
$(".next", parent).click(function() { 
$(".content", parent).html("Next Page Content"); 
}); 
}); 
</script> 
<div id="complex_page_segment"> 
<input type="button" value="Previous Page" class="previous" /> 
<input type="button" value="Next Page" class="next" /> 
<div class="content">Page Content</div> 
</div>

将HTML片段中的JavaScript提取为一个文件
这也是自然而然就想到的,特别是HTML片段中JavaScript代码比较多的情况下,
提取为一个JS文件,让浏览器帮忙缓存不失为一种好方法。
1. 重新定义pages2_2.txt
<script type="text/javascript"> 
$(function() { 
setup(); 
}); 
</script> 
<script src="pages2_2.js" type="text/javascript"></script> 
<div id="complex_page_segment"> 
<input type="button" value="Previous Page" class="previous" /> 
<input type="button" value="Next Page" class="next" /> 
<div class="content">Page Content</div> 
</div>

2. pages2_2.js
function setup() { 
var parent = $("#complex_page_segment"); 
$(".previous", parent).click(function() { 
$(".content", parent).html("Previous Page Content"); 
}); 
$(".next", parent).click(function() { 
$(".content", parent).html("Next Page Content"); 
}); 
}

3. 运行,居然报错! 

在多个页面使用同一个HTML片段《续》

问题分析
错误信息是 setup 这个函数没有定义,但是从Firebug中我们明显看到pages2_2.js的确被加载了。
那个极有可能是在 pages2_2.js 加载之前就调用了 setup 这个函数。
但是我们的setup 函数调用是放在jQuery的 $(function(){ }) 之中的,也就是在页面加载完毕才调用的。

其实现在问题已经很明显了,在AJAX返回页面片段的时候,整个页面是已经加载完成了,也就是DOM Ready。
所以在页面片段中:

$(function() { 
setup(); 
});

和下面直接调用是等价的:
setup();

解决问题
对于这个问题,我们有三种解决办法。
1. 将外部JS文件在页面中加载,而不是在AJAX返回的HTML片段。

2. 我们可以通过JavaScript先加载外部JS,再加载纯粹的HTML片段。
看一下pages2_3.htm的实现:

<script type="text/javascript"> 
$(function() { 
$("#clickToInsert").click(function() { 
$.getScript("pages2_2.js", function() { 
$.get("service.ashx?file=pages2_3.txt", function(data) { 
$("#placeholder").html(data); 
}, "text"); 
}); 
}); 
}); 
</script> 
<input type="button" id="clickToInsert" value="Insert HTML" /> 
<div id="placeholder"> 
</div>

3. 利用JavaScript在页面上是顺序加载的特性,将HTML片段中外部JS引用放在最上面
pages2_4.htm:
<script type="text/javascript"> 
$(function() { 
$("#clickToInsert").click(function() { 
$.get("service.ashx?file=pages2_4.txt", function(data) { 
$("#placeholder").html(data); 
}, "text"); 
}); 
}); 
</script> 
<input type="button" id="clickToInsert" value="Insert HTML" /> 
<div id="placeholder"> 
</div>

pages2_4.txt:
<script src="pages2_2.js" type="text/javascript"></script> 
<script type="text/javascript"> 
setup(); 
</script> 
<div id="complex_page_segment"> 
<input type="button" value="Previous Page" class="previous" /> 
<input type="button" value="Next Page" class="next" /> 
<div class="content"> 
Page Content</div> 
</div>

可能你会觉得第三种方法没有必要,但是如果你碰到这样的需求,你就知道第三种方法的重要性了。

不要在每个页面都加载这个JS文件
调用者不知道一个HTML片段关联哪些JS文件
============================================================
关于JS的顺序执行特性
可能有人对这个特性并不是很清楚,我就通过一个例子来说明。

<html> 
<head> 
<title></title> 
<script src="js1.js" type="text/javascript"></script> 
<script src="js2.js" type="text/javascript"></script> 
<script type="text/javascript"> 
console.log("after js2:" + new Date().toLocaleTimeString()); 
</script> 
</head> 
<body> 
</body> 
</html>

js1.js:
console.log("start load js1:" + new Date().toLocaleTimeString()); 
// 中间是很长很长的一段JavaScript,有12M之多 
console.log("end load js2:" + new Date().toLocaleTimeString());

js2.js:
console.log("load js2:" + new Date().toLocaleTimeString());

我们来看下Firebug的记录: 

在多个页面使用同一个HTML片段《续》

在多个页面使用同一个HTML片段《续》

可以看到,虽然js2.js更早的被加载,但是还是js1.js执行结束之后,才开始执行js2.js。
源代码下载

Javascript 相关文章推荐
prototype 学习笔记整理
Jul 17 Javascript
深入理解JavaScript系列(13) This? Yes,this!
Jan 18 Javascript
js实现Select列表各项上移和下移的方法
Aug 14 Javascript
一个超简单的jQuery回调函数例子(分享)
Aug 08 Javascript
微信小程序 地图定位简单实例
Oct 14 Javascript
Angularjs分页查询的实现
Feb 24 Javascript
微信小程序组件 marquee实例详解
Jun 23 Javascript
vue获取dom元素注意事项
Dec 28 Javascript
Vue单页面应用保证F5强刷不清空数据的解决方案
Jan 31 Javascript
vue.js 实现点击展开收起动画效果
Jul 07 Javascript
JavaScript实现京东放大镜效果
Dec 03 Javascript
JS中forEach()、map()、every()、some()和filter()的用法
May 11 Javascript
在多个页面使用同一个HTML片段的代码
Mar 04 #Javascript
如何确保JavaScript的执行顺序 之实战篇
Mar 03 #Javascript
如何确保JavaScript的执行顺序 之jQuery.html并非万能钥匙
Mar 03 #Javascript
如何确保JavaScript的执行顺序 之jQuery.html深度分析
Mar 03 #Javascript
jQuery 操作option的实现代码
Mar 03 #Javascript
基于Jquery的$.cookie()实现跨越页面tabs导航实现代码
Mar 03 #Javascript
jquery中实现简单的tabs插件功能的代码
Mar 02 #Javascript
You might like
php设计模式 Decorator(装饰模式)
2011/06/26 PHP
基于PHP服务端图片生成缩略图的方法详解
2013/06/20 PHP
PHP防范SQL注入的具体方法详解(测试通过)
2014/05/09 PHP
php session_decode函数用法讲解
2019/05/26 PHP
PHP如何使用array_unshift()在数组开头插入元素
2020/09/01 PHP
JS类库Bindows1.3中的内存释放方式分析
2007/03/08 Javascript
JS 字符串连接[性能比较]
2009/05/10 Javascript
jQuery中调用WebService方法小结
2011/03/28 Javascript
js中使用DOM复制(克隆)指定节点名数据到新的XML文件中的代码
2011/07/27 Javascript
遍历jquery对象的代码分享
2011/11/02 Javascript
jQuery 2.0.3 源码分析之core(一)整体架构
2014/05/27 Javascript
jquery中map函数遍历数组用法实例
2015/05/18 Javascript
jquery 中ajax执行的优先级
2015/06/22 Javascript
微信小程序事件对象中e.target和e.currentTarget的区别详解
2019/05/08 Javascript
JS实现返回上一页并刷新页面的方法分析
2019/07/16 Javascript
Smartour 让网页导览变得更简单(推荐)
2019/07/19 Javascript
webpack + vue 打包生成公共配置文件(域名) 方便动态修改
2019/08/29 Javascript
jQuery设置下拉框显示与隐藏效果的方法分析
2019/09/15 jQuery
JavaScript工具库MyTools详解
2020/01/01 Javascript
详解Vue 数据更新了但页面没有更新的 7 种情况汇总及延伸总结
2020/05/28 Javascript
[09:23]国际邀请赛采访专栏:iG战队VK,Tongfu战队Cu
2013/08/05 DOTA
[26:40]DOTA2上海特级锦标赛A组资格赛#1 Secret VS MVP.Phx第一局
2016/02/25 DOTA
Flask SQLAlchemy一对一,一对多的使用方法实践
2013/02/10 Python
Python建立Map写Excel表实例解析
2018/01/17 Python
Python的argparse库使用详解
2018/10/09 Python
python抓取京东小米8手机配置信息
2018/11/13 Python
对pandas处理json数据的方法详解
2019/02/08 Python
python双端队列原理、实现与使用方法分析
2019/11/27 Python
python tkinter 设置窗口大小不可缩放实例
2020/03/04 Python
python openpyxl模块的使用详解
2021/02/25 Python
安纳塔拉酒店度假村及水疗官方网站:Anantara Hotel
2016/08/25 全球购物
捷克领先的户外服装及配件市场零售商:ALPINE PRO
2018/01/09 全球购物
京东奢侈品:全球奢侈品牌
2018/03/17 全球购物
护士进修自我鉴定
2014/02/07 职场文书
终止劳动合同证明书样本
2014/11/19 职场文书
惊涛骇浪观后感
2015/06/05 职场文书