关闭

由单页应用引出的胡言乱语

533人阅读 评论(0) 收藏 举报
分类:

单页应用很火。翻开知乎,看到“单页应用的好处”,到处可见:前后端分离等等云云。

它是个啥?《单页Web应用----JavaScript从前端到后端》赫然写着,“单页应用指的是在浏览器中运行的应用,在使用期间页面不会重新加载”。

举个例子,传统web的导航条,点一个菜单,啪发送一个请求给服务器,然后展示一个新页面;然后点另外一个菜单,啪又发送一个请求个服务器,然后又展示一个新页面。这页面是重新加载的,是崭新的。但是【单页应用】不会,你点击一个导航条,它甚至都不会发送请求给服务器,只是默默的局部刷新一下内容页(比如AngularJS的路由)。

这是怎样实现的?抛开一堆花里胡哨的JS库不看,就从它们的根---JavaScript看起。JS语言的两个重点:1.DOM操作 2.Ajax请求。

00:我们先最猥琐的方式实现一个单页应用:

<!DOCTYPE HTML>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
        <script type="text/javascript">
        var pages = {1:"这是页面1",2:"这是页面2"};
        window.onload = function(){
            document.getElementById("content").innerHTML = pages[1];
        }
        function clickPage(id){
            document.getElementById("content").innerHTML = pages[id];
        }
        </script>
    </head>
    <body>
        <div style="width:100%;height:80px;">
            <a href="javascript:clickPage(1)">页面1</a>
            <a href="javascript:clickPage(2)">页面2</a>
        </div>
        <div id="content">
        </div>
    </body>
</html>


其实就是根据点击的菜单,用innerHTML将页面嵌入到div中;pages中的内容可以发散思维啊,就是可以填入巨复杂的html串,里面包含js进行ajax请求来刷新自己/展示数据等等。这就是一个单页应用,只不过写代码的人应该是相当痛苦。

01:然后就有人说,把每个页面的html独立到单独的代码文件中吧。不要直接放在字符串中,要不然太痛苦了。然后就有了下面的一种实现:

index1.html

index2.html

里面各种html/js代码,利用ajax请求来读取数据发送请求等等。

然后index.html这样实现:

<!DOCTYPE HTML>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html;charset=utf-8"?>
        <script type="text/javascript" src="jquery-1.10.2.js"></script>
        <script type="text/javascript">
        jQuery(document).ready(function(){
            jQuery("#content").load("index1.html");
        });
        function clickPage(id){
            jQuery("#content").load("index"+id+".html");
        }
        </script>
    </head>
    <body>
        <div style="width:100%;height:80px;">
            <a href="javascript:clickPage(1)">页面1</a>
            <a href="javascript:clickPage(2)">页面2</a>
        </div>
        <div id="content">
        </div>
    </body>
</html>

是不是清爽了很多?导航切换时也只是局部刷新了content的内容,没有重新加载页面。

02:有人说,还是太复杂了,再让它清爽一点吧。于是就有了类似下面的实现:

<!DOCTYPE HTML>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html;charset=utf-8"?>
        <script type="text/javascript" src="jquery-1.10.2.js"></script>
        <script type="text/javascript">
        jQuery(document).ready(function(){
            jQuery("#content").load("index1.html");
            jQuery("a").bind("click",function(event){
                if(jQuery(this).attr("href")=="#page1"){
                    jQuery("#content").load("index1.html");
                }else if(jQuery(this).attr("href")=="#page2"){
                    jQuery("#content").load("index2.html");
                }
                event.stopPropagation(); 
            });
        });
        </script>
    </head>
    <body>
        <div style="width:100%;height:80px;">
            <a href="#page1">页面1</a>
            <a href="#page2">页面2</a>
        </div>
        <div id="content">
        </div>
    </body>
</html>

03.这时又有人说了,我甚至不希望关心点击导航时,页面是如何局部刷新的。我只期望指定某个导航对应哪个页面即可。OK,那我们就对它的方法进行一下抽象吧。

route.js

function routeProvider(menu){
    var dict = Array();
    for(var key in menu){
        dict[key] = menu[key]["template"];
    }
    jQuery("a").bind("click",function(event){
        jQuery("#content").load(dict[jQuery(this).attr("href")]);
        event.stopPropagation(); 
    });
}

index.html的实现:

<!DOCTYPE HTML>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html;charset=utf-8"?>
        <script type="text/javascript" src="jquery-1.10.2.js"></script>
        <script type="text/javascript" src="route.js"></script>
        <script type="text/javascript">
        jQuery(document).ready(function(){
            jQuery("#content").load("index1.html");
            routeProvider({
                "#page1":{"template":"index1.html"},
                "#page2":{"template":"index2.html"},
            });
        });
        </script>
    </head>
    <body>
        <div style="width:100%;height:80px;">
            <a href="#page1">页面1</a>
            <a href="#page2">页面2</a>
        </div>
        <div id="content">
        </div>
    </body>
</html>

OK,你甚至可以沿着这个思路,继续封装,最后实现一个类似AngularJS路由功能类似的东东。

框架API是我非常不愿意记忆的API之一,我觉得毫无意义,只是他人提出来的理念,让你照着他的意思玩。太耗费大脑的存储空间了,而且现在的JS库也实在太多了。







0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:1393516次
    • 积分:15332
    • 等级:
    • 排名:第713名
    • 原创:473篇
    • 转载:64篇
    • 译文:5篇
    • 评论:193条
    最新评论