一、概念
①在一个页面上实现网站的大部分功能,就是单页面应用程序,是一种常见的网页开发模式。
②整个网站就只有一个Html文件,每次在切换页面时,不需要请求服务器,只要通过本地的js来切换即可。这样可以减小服务器压力、增强用户体验,增加app的使用流畅性。
二、特点
①优点:
- 具有桌面应用的即时性、网站的可移植性和可访问性。
- 用户体验好、快,内容的改变不需要重新加载整个页面,web应用更具响应性和更令人着迷。
- 基于上面一点,SPA相对对服务器压力小。
- 良好的前后端分离。SPA和RESTful架构一起使用,后端不再负责模板渲染、输出页面工作,web前端和各种移动终端地位对等,后端API通用化。
- 对前端人员javascript技能要求更高,促使团队技能提升。
②缺点:
- 分功能模块的鉴权不好实现。
- 不利于SEO搜索引擎优化
- 初次加载耗时相对增多
- 导航不可用,如果一定要导航需要自行实现前进、后退。
- 对开发人员技能水平、开发成本高。
三、具体应用
①单页应用肯定是要使用一些框架的,比如Vue、Angular、React等,但是使用 Vue、Angular、React 也不一定是做单页,做单页一定是前后端分离的方式,如果有 SEO 需求,则不要做成单页
②具体使用的网站:网易云音乐、coding、Gmail等
四、模拟单页应用
①historyAPI方案,参考之前的章:历史相关API
②哈希(路由)方案:使用location.hash和hashchange事件实现路由
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>模拟单页面应用</title> <style> *{ padding: 0; margin: 0; } body{ background-color: #f7f7f7; font-family: Arial, Helvetica, sans-serif; } header{ background: #242424; border-bottom: #000; } .wrapper{ width: 1100px; height: 70px; margin: 0 auto; } .wrapper h1{ float: left; width: 176px; height: 69px; background: url("topbar.png") no-repeat 0 0; font-size: 0; } .wrapper ul{ list-style: none; } .wrapper ul li{ float: left; height: 70px; } .wrapper ul li.now, .wrapper ul li:hover{ background: red; } .wrapper ul li a{ padding: 0 20px; display: block; color: #fff; line-height: 70px; text-decoration: none; } .content{ width: 1100px; margin: 0 auto; font-size: 100px; text-align: center; } </style> </head> <body> <header> <div class="wrapper"> <h1>网易云音乐</h1> <ul> <!-- 为了和普通的锚点作区分,所以这里的路径加了一个前缀# --> <li><a href="#/">发现音乐</a></li> <li><a href="#/my">我的音乐</a></li> <li><a href="#/friend">朋友</a></li> </ul> </div> </header> <!-- 其它页面都需要显示在这个容器中 --> <div class="container" id="container"></div> <script src="jquery.js"></script> <script> // 通过注册 window.onhashchange 事件来监听 hahs(锚点)的改变 // url 地址发生改变之后,就解析 hash 中的路径标识 // 然后根据不同的路径标识渲染不同的页面到单页面中的容器中 window.onhashchange=function(){ var hash=window.location.hash.substr(1);//去除# if(hash==='/'){ $.get('./find.html',function(data){ $('#container').html(data); console.log(data) }); }else if(hash==='/my'){ $.get('./my.html',function(data){ $('#container').html(data); }); }else if(hash==='/friend'){ $.get('./friend.html',function(data){ $('#container').html(data); }); } } </script> </body> </html>