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

  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。

  源代码下载