在多个页面使用同一个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 相关文章推荐
Jquery选择器 $实现原理
Dec 02 Javascript
jQuery EasyUI API 中文文档 - Parser 解析器
Sep 29 Javascript
Extjs3.0 checkboxGroup 动态添加item实现思路
Aug 14 Javascript
编写自己的jQuery提示框(Tip)插件
Feb 05 Javascript
浅析JavaScript中的事件机制
Jun 04 Javascript
js实现带缓冲效果的仿QQ面板折叠菜单代码
Sep 06 Javascript
JavaScript构造函数详解
Dec 27 Javascript
Node.js如何自动审核团队的代码
Jul 20 Javascript
JavaScript 数组- Array的方法总结(推荐)
Jul 21 Javascript
原生JS实现左右箭头选择日期实例代码
Mar 14 Javascript
JavaScript之解构赋值的理解
Jan 30 Javascript
JavaScript事件的委托(代理)的用法示例详解
Feb 18 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+JS无限级可伸缩菜单详解(简单易懂)
2007/01/02 PHP
在WINDOWS中设置计划任务执行PHP文件的方法
2011/12/19 PHP
解析zend studio中直接导入svn中的项目的方法步骤
2013/06/21 PHP
thinkphp命名空间用法实例详解
2015/12/30 PHP
PHP编写的图片验证码类文件分享
2016/06/06 PHP
php实现背景图上添加圆形logo图标的方法
2016/11/17 PHP
php实现微信模拟登陆、获取用户列表及群发消息功能示例
2017/06/28 PHP
js下关于onmouseout、事件冒泡的问题经验小结
2010/12/09 Javascript
kmock javascript 单元测试代码
2011/02/06 Javascript
Javascript中valueOf与toString区别浅析
2013/03/19 Javascript
js弹出层(jQuery插件形式附带reLoad功能)
2013/04/12 Javascript
JS+CSS实现可拖动的弹出提示框
2015/02/16 Javascript
nodejs爬虫抓取数据乱码问题总结
2015/07/03 NodeJs
JavaScript仿淘宝页面图片滚动加载及刷新回顶部的方法解析
2016/05/24 Javascript
针对BootStrap中tabs控件的美化和完善(推荐)
2016/07/06 Javascript
工作中比较实用的JavaScript验证和数据处理的干货(经典)
2016/08/03 Javascript
JS/jQuery实现DIV延时几秒后消失或显示的方法
2018/02/12 jQuery
微信小程序实现自定义modal弹窗封装的方法
2018/06/15 Javascript
Node.js控制台彩色输出的方法与原理实例详解
2019/12/01 Javascript
Vue中实现回车键切换焦点的方法
2020/02/19 Javascript
VUE动态生成word的实现
2020/07/26 Javascript
vue实现标签云效果的示例
2020/11/09 Javascript
[46:10]2014 DOTA2国际邀请赛中国区预选赛 CnB VS HGT
2014/05/21 DOTA
[00:30]塑造者的传承礼包-戴泽“暗影之焰”套装展示视频
2014/04/04 DOTA
学习python 之编写简单乘法运算题
2016/02/27 Python
Python中基础的socket编程实战攻略
2016/06/01 Python
Python 3.x 连接数据库示例(pymysql 方式)
2017/01/19 Python
Python中函数及默认参数的定义与调用操作实例分析
2017/07/25 Python
python二维键值数组生成转json的例子
2019/12/06 Python
解决springboot yml配置 logging.level 报错问题
2020/02/21 Python
python 6行代码制作月历生成器
2020/09/18 Python
用python对excel进行操作(读,写,修改)
2020/12/25 Python
财务管理个人自荐书范文
2013/11/24 职场文书
酒店营销策划方案
2014/02/07 职场文书
学校三八妇女节活动总结
2015/02/06 职场文书
证券区域经理岗位职责
2015/04/10 职场文书