在多个页面使用同一个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 相关文章推荐
用Javascript实现锚点(Anchor)间平滑跳转
Sep 08 Javascript
javascript实现点击按钮弹出一个可关闭层窗口同时网页背景变灰的方法
May 13 Javascript
mvc中form表单提交的三种方式(推荐)
Aug 10 Javascript
js实现上传文件添加和删除文件选择框
Oct 24 Javascript
简单实现jQuery级联菜单
Jan 09 Javascript
Vue项目webpack打包部署到服务器的实例详解
Jul 17 Javascript
详细介绍RxJS在Angular中的应用
Sep 23 Javascript
fetch 使用及如何接收JS传值
Nov 11 Javascript
vue实现某元素吸顶或固定位置显示(监听滚动事件)
Dec 13 Javascript
vue.js移动数组位置,同时更新视图的方法
Mar 08 Javascript
vue-cli3全面配置详解
Nov 14 Javascript
我要点爆”微信小程序云开发之项目建立与我的页面功能实现
May 26 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 date与gmdate的获取日期的区别
2010/02/08 PHP
php中session_unset与session_destroy的区别分析
2011/06/16 PHP
深入PHP运行环境配置的详解
2013/06/04 PHP
PHP中使用GD库创建圆形饼图的例子
2014/11/19 PHP
php目录遍历函数opendir用法实例
2014/11/20 PHP
Symfony2使用第三方库Upload制作图片上传实例详解
2016/02/04 PHP
浅谈php中的循环while、do...while、for、foreach四种循环
2016/11/05 PHP
php实现有序数组旋转后寻找最小值方法
2018/09/27 PHP
thinkPHP框架实现的简单计算器示例
2018/12/07 PHP
JavaScript表单常用验证集合
2008/01/16 Javascript
Javascript的闭包详解
2014/12/26 Javascript
微信小程序 action-sheet 反馈上拉菜单简单实例
2017/05/11 Javascript
vue使用drag与drop实现拖拽的示例代码
2017/09/07 Javascript
jQuery实现所有验证通过方可提交的表单验证
2017/11/21 jQuery
vue.js 底部导航栏 一级路由显示 子路由不显示的解决方法
2018/03/09 Javascript
解决vue中post方式提交数据后台无法接收的问题
2018/08/11 Javascript
解决vue js IOS H5focus无法自动弹出键盘的问题
2018/08/30 Javascript
Node.js的进程管理的深入理解
2019/01/09 Javascript
「中高级前端面试」JavaScript手写代码无敌秘籍(推荐)
2019/04/08 Javascript
详解如何模拟实现node中的Events模块(通俗易懂版)
2019/04/15 Javascript
vue css 引入asstes中的图片无法显示的四种解决方法
2020/03/16 Javascript
JavaScript 判断数据类型的4种方法
2020/09/11 Javascript
python中reload(module)的用法示例详解
2017/09/15 Python
numpy数组拼接简单示例
2017/12/15 Python
浅谈Django中的数据库模型类-models.py(一对一的关系)
2018/05/30 Python
详解Python3的TFTP文件传输
2018/06/26 Python
PyQt5内嵌浏览器注入JavaScript脚本实现自动化操作的代码实例
2019/02/13 Python
关于tf.nn.dynamic_rnn返回值详解
2020/01/20 Python
python连接打印机实现打印文档、图片、pdf文件等功能
2020/02/07 Python
HTML实现代码雨源码及效果示例
2020/02/25 HTML / CSS
C#面试题问题集
2016/04/02 面试题
经贸日语毕业生自荐信
2013/11/03 职场文书
学习决心书
2014/03/11 职场文书
副董事长岗位职责
2014/04/02 职场文书
学生会生活部工作总结2015
2015/03/31 职场文书
详解JavaScript中的执行上下文及调用堆栈
2021/04/29 Javascript