在多个页面使用同一个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 相关文章推荐
一个封装js代码-----展开收起效果示例
Jul 03 Javascript
js中style.display=&quot;&quot;无效的解决方法
Oct 30 Javascript
第一次接触神奇的Bootstrap表单
Jul 27 Javascript
原生js实现网易轮播图效果
Apr 10 Javascript
laydate.js日期时间选择插件
Jan 04 Javascript
JavaScript高阶函数_动力节点Java学院整理
Jun 28 Javascript
微信小程序画布圆形进度条显示效果
Nov 17 Javascript
vue组件 keep-alive 和 transition 使用详解
Oct 11 Javascript
微信小程序自定义头部导航栏(组件化)
Nov 15 Javascript
JS脚本实现定时到网站上签到/签退功能
Apr 22 Javascript
Vue使用CDN引用项目组件,减少项目体积的步骤
Oct 30 Javascript
JS数组索引检测中的数据类型问题详解
Jan 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获取地址栏信息的代码
2008/10/08 PHP
PHP爬虫之百万级别知乎用户数据爬取与分析
2016/01/22 PHP
PHP中获取文件创建日期、修改日期、访问时间的方法
2016/11/05 PHP
ExtJs中简单的登录界面制作方法
2010/08/19 Javascript
javascript对talbe进行动态添加、删除、验证实现代码
2012/03/29 Javascript
js onkeypress与onkeydown 事件区别详细说明
2012/12/13 Javascript
简单常用的幻灯片播放实现代码
2013/09/25 Javascript
javascript处理表单示例(javascript提交表单)
2014/04/28 Javascript
jquery实现的树形目录实例
2015/06/26 Javascript
鼠标悬停小图标显示大图标
2016/01/22 Javascript
NodeJS仿WebApi路由示例
2017/02/28 NodeJs
iView-admin 动态路由问题的解决方法
2018/10/03 Javascript
微信小程序如何播放腾讯视频的实现
2019/09/20 Javascript
JS实现移动端双指缩放和旋转方法
2019/12/13 Javascript
JavaScript ECMA-262-3 深入解析(一):执行上下文实例分析
2020/04/25 Javascript
WebPack工具运行原理及入门教程
2020/12/02 Javascript
[03:06]V社市场总监Dota2项目负责人Erik专访:希望更多中国玩家加入DOTA2
2014/07/11 DOTA
[40:12]Liquid vs Chaos 2019国际邀请赛小组赛 BO2 第二场 8.15
2019/08/16 DOTA
[00:56]PWL开团时刻DAY8——追追追追追!
2020/11/09 DOTA
Python 调用Java实例详解
2017/06/02 Python
python 表达式和语句及for、while循环练习实例
2017/07/07 Python
详解HTML5 data-* 自定义属性
2018/01/24 HTML / CSS
俄罗斯最大的隐形眼镜销售网站:Ochkov.Net
2021/02/07 全球购物
C#笔试题
2015/07/14 面试题
产品工艺师的岗位职责
2013/11/15 职场文书
保安拾金不昧表扬信
2014/01/15 职场文书
致全体运动员广播稿
2014/02/01 职场文书
施工员岗位职责
2014/03/16 职场文书
交通安全责任书范本
2014/07/24 职场文书
家具商场的活动方案
2014/08/16 职场文书
我的中国梦演讲稿初中篇
2014/08/19 职场文书
2014工程部年度工作总结
2014/12/17 职场文书
工程款催款函
2015/06/24 职场文书
2016三八妇女节校园广播稿
2015/12/17 职场文书
2016年敬老月活动总结
2016/04/05 职场文书
kubernetes集群搭建Zabbix监控平台的详细过程
2022/07/07 Servers