zoukankan      html  css  js  c++  java
  • 如何在多个页面使用同一个HTML片段《续》


    上一篇文章中我们使用textarea来模拟AJAX的返回结果,造成了一些误解。

    这里我们首先用asp.net的Generic Handler做一个简单的后台来重现这个AJAX过程。
    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. 运行,居然报错! 




    问题分析

    错误信息是 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的记录: 
     

     



    可以看到,虽然js2.js更早的被加载,但是还是js1.js执行结束之后,才开始执行js2.js。

    源代码下载




  • 相关阅读:
    1.7 All components require plug-in?
    1.6 Why only in China?
    1.5 A better alternative thing: React Native
    1.4 The usage of plug-in
    1.3 History of Android Plug-in Programing
    SQL Server 查询请求
    matplotlib 绘图的核心原理
    数据加密 第六篇:透明文件加密
    数据加密 第五篇:非对称密钥
    SSIS 数据类型 第二篇:变量的数据类型
  • 原文地址:https://www.cnblogs.com/sanshi/p/1546317.html
Copyright © 2011-2022 走看看