在多个页面使用同一个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制作简单的数字键盘
Apr 24 Javascript
jquery插件tytabs.jquery.min.js实现渐变TAB选项卡效果
Aug 25 Javascript
JavaScript如何实现图片懒加载(lazyload) 提高用户体验(增强版)
Nov 30 Javascript
bootstrap选项卡使用方法解析
Jan 11 Javascript
浅谈vue中慎用style的scoped属性
Nov 28 Javascript
Node.js上传文件功能之服务端如何获取文件上传进度
Feb 05 Javascript
JS数组求和的常用方法实例小结
Jan 07 Javascript
ECharts地图绘制和钻取简易接口详解
Jul 12 Javascript
layuiAdmin循环遍历展示商品图片列表的方法
Sep 16 Javascript
js实现拖动缓动效果
Jan 13 Javascript
vue配置多代理服务接口地址操作
Sep 08 Javascript
vue使用require.context实现动态注册路由
Dec 25 Vue.js
在多个页面使用同一个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
CPU步进是什么意思?i3-9100F B0步进和U0步进区别知识科普
2020/03/17 数码科技
PHP 文件系统详解
2012/09/13 PHP
浅谈PHP解析URL函数parse_url和parse_str
2014/11/11 PHP
Symfony2实现在doctrine中内置数据的方法
2016/02/05 PHP
js修改table中Td的值(定义td的单击事件)
2013/01/10 Javascript
原生js事件的添加和删除的封装
2014/07/01 Javascript
DOM操作一些常用的属性汇总
2015/03/13 Javascript
jQuery实现批量判断表单中文本框非空的方法(2种方法)
2015/12/09 Javascript
javascript禁止超链接跳转的方法
2016/02/02 Javascript
JS 动态加载js文件和css文件 同步/异步的两种简单方式
2016/09/23 Javascript
PHP获取当前页面完整URL的方法
2016/12/02 Javascript
详解JavaScript中数组的reduce方法
2016/12/02 Javascript
清除js缓存的多种方法总结
2016/12/09 Javascript
详解AngularJS用Interceptors来统一处理HTTP请求和响应
2017/06/08 Javascript
vue2.0$nextTick监听数据渲染完成之后的回调函数方法
2018/09/11 Javascript
浅谈Vue项目骨架屏注入实践
2019/08/05 Javascript
javascript for循环性能测试示例
2019/08/07 Javascript
jquery 遍历hash操作示例【基于ajax交互】
2019/10/12 jQuery
js实现tab栏切换效果
2020/08/02 Javascript
vue 使用lodash实现对象数组深拷贝操作
2020/09/10 Javascript
微信小程序自定义支持图片的弹窗
2020/12/21 Javascript
用Python编写一个简单的俄罗斯方块游戏的教程
2015/04/03 Python
python中利用zfill方法自动给数字前面补0
2018/04/10 Python
python使用opencv在Windows下调用摄像头实现解析
2019/11/26 Python
python os.rename实例用法详解
2020/12/06 Python
把富文本的回车转为br标签
2019/08/09 HTML / CSS
htmlentities() 和 htmlspecialchars()有什么区别
2015/07/01 面试题
Ajax请求总共有多少种Callback
2016/07/17 面试题
会计工作决心书
2014/03/11 职场文书
企业承诺书格式
2014/05/21 职场文书
小学运动会报道稿
2014/10/04 职场文书
公务员政审材料
2014/12/23 职场文书
2016继续教育研修日志
2015/11/13 职场文书
小学音乐课教学反思
2016/02/18 职场文书
旅游安全责任协议书
2016/03/22 职场文书
解决Pytorch半精度浮点型网络训练的问题
2021/05/24 Python