阿里巴巴校招2017前端笔试题目 -- 原生js/html5 实现一个路由
2017-04-28 10:36
821 查看
阿里巴巴校招2017前端笔试题目:
1)路由有什么缺点?
2)原生js/html5 实现一个路由
缺点:
* 使用浏览器的前进,后退键的时候会重新发送请求,没有合理地利用缓存
* 单页面无法记住之前滚动的位置,无法在前进,后退的时候记住滚动的位置
路由的概念:
* 路由是根据不同的 url 地址展示不同的内容或页面
* 前端路由就是把不同路由对应不同的内容或页面的任务交给前端来做,之前是通过服务端根据 url 的不同返回不同的页面实现的。
我们直接来看两个例子,一个是hash结构的,这是在Html5 的history api出现之前的解决方案;一个是基于history api实现的。
- hash
history
前端的路由和后端的路由在实现技术上不一样,但是原理都是一样的。
两个方法均有三个参数:一个状态对象、一个标题(现在会被忽略),一个可选的URL地址
状态对象(state object) — 一个JavaScript对象,与用pushState()方法创建的新历史记录条目关联。无论何时用户导航到新创建的状态,popstate事件都会被触发,并且事件对象的state属性都包含历史记录条目的状态对象的拷贝。
任何可序列化的对象都可以被当做状态对象。因为FireFox浏览器会把状态对象保存到用户的硬盘,这样它们就能在用户重启浏览器之后被还原,我们强行限制状态对象的大小为640k。如果你向pushState()方法传递了一个超过该限额的状态对象,该方法会抛出异常。如果你需要存储很大的数据,建议使用sessionStorage或localStorage。
pushState 用于向 history 添加当前页面的记录,而 replaceState 和 pushState 的用法完全一样,唯一的区别就是它用于修改当前页面在 history 中的记录。
两者的一个表现的区别是:在浏览器上点击后退键的时候,使用pushState的会正常按照点击的顺序依次返回,而使用replaceState的只是替换,不会返回,会直接返回到pushState的记录。
index.html
**
simple-history.js**
参考阅读:
- 原生JS实现一个简单的前端路由(路由实现的原理)
- 从 React Router 谈谈路由的那些事
1)路由有什么缺点?
2)原生js/html5 实现一个路由
缺点:
* 使用浏览器的前进,后退键的时候会重新发送请求,没有合理地利用缓存
* 单页面无法记住之前滚动的位置,无法在前进,后退的时候记住滚动的位置
路由的概念:
* 路由是根据不同的 url 地址展示不同的内容或页面
* 前端路由就是把不同路由对应不同的内容或页面的任务交给前端来做,之前是通过服务端根据 url 的不同返回不同的页面实现的。
我们直接来看两个例子,一个是hash结构的,这是在Html5 的history api出现之前的解决方案;一个是基于history api实现的。
- hash
http://10.0.0.1/ http://10.0.0.1/#/about http://10.0.0.1/#/concat
history
http://10.0.0.1/ http://10.0.0.1/about http://10.0.0.1/concat
前端的路由和后端的路由在实现技术上不一样,但是原理都是一样的。
1.hash
关键是监控两个事件,一个是页面加载进来的时候触发load,一个是hash改变的时候触发
hashchange。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <ul> <li><a href="#/">turn white</a></li> <li><a href="#/blue">turn blue</a></li> <li><a href="#/green">turn green</a></li> </ul> <script> class Router { constructor() { this.routes = {}; this.curUrl = ""; } route(path, callback) { this.routes[path] = callback || function() {}; } refresh() { this.curUrl = location.hash.slice(1) || '/'; this.routes[this.curUrl](); } init() { window.addEventListener('load', this.refresh.bind(this), false); window.addEventListener('hashchange', this.refresh.bind(this), false); } } var router = new Router(); router.init(); var content = document.querySelector('body'); // change Page anything function changeBgColor(color) { content.style.backgroundColor = color; } router.route('/', function() { changeBgColor('white'); }); router.route('/blue', function() { changeBgColor('blue'); }); router.route('/green', function() { changeBgColor('green'); }); </script> </body> </html>
2.history api
html5 增加了两个方法,分别是pushState,
replaceState.
两个方法均有三个参数:一个状态对象、一个标题(现在会被忽略),一个可选的URL地址
状态对象(state object) — 一个JavaScript对象,与用pushState()方法创建的新历史记录条目关联。无论何时用户导航到新创建的状态,popstate事件都会被触发,并且事件对象的state属性都包含历史记录条目的状态对象的拷贝。
任何可序列化的对象都可以被当做状态对象。因为FireFox浏览器会把状态对象保存到用户的硬盘,这样它们就能在用户重启浏览器之后被还原,我们强行限制状态对象的大小为640k。如果你向pushState()方法传递了一个超过该限额的状态对象,该方法会抛出异常。如果你需要存储很大的数据,建议使用sessionStorage或localStorage。
pushState 用于向 history 添加当前页面的记录,而 replaceState 和 pushState 的用法完全一样,唯一的区别就是它用于修改当前页面在 history 中的记录。
两者的一个表现的区别是:在浏览器上点击后退键的时候,使用pushState的会正常按照点击的顺序依次返回,而使用replaceState的只是替换,不会返回,会直接返回到pushState的记录。
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Simple History</title> </head> <body> <a class="push" href="?push-one">Push One</a> <a class="push" href="?push-two">Push Two</a> <a class="push" href="?push-three">Push Three</a> <a class="replace" href="?replace-one">Replace One</a> <a class="replace" href="?replace-two">Replace Two</a> <a class="replace" href="?replace-three">Replace Three</a> <ul id="log"></ul> <script src="simple-history.js"></script> <script src="https://cdn.bootcss.com/jquery/1.7.1/jquery.min.js"></script> <script> (function() { if (!SimpleHistory.supported) { return; } SimpleHistory.start(function(path) { console.log("match", path); document.title = "Simple History - " + path; $("<li>").text("match: " + path).appendTo("#log"); }); $("a:not([href^=http])").click(function(event) { if (event.metaKey || event.shiftKey || event.ctrlKey) { return; } event.preventDefault(); var path = $(event.target).attr("href"); if ($(event.target).is(".push")) { SimpleHistory.pushState(event.target.href); } else { SimpleHistory.replaceState(event.target.href); } }); }()) </script> </body> </html>
**
simple-history.js**
(function(window, undefined) { var initial = location.href; window.SimpleHistory = { supported: !!(window.history && window.history.pushState), pushState: function(fragment, state) { state = state || {}; history.pushState(state, null, fragment); this.notify(state); }, replaceState: function(fragment, state) { state = state || {}; history.replaceState(state, null, fragment); }, notify: function(state) { console.log(location.pathname,location.search); this.matcher(location.pathname + location.search, state); }, start: function(matcher) { this.matcher = matcher; window.addEventListener("popstate", function(event) { // workaround to always ignore first popstate event (Chrome) // a timeout isn't reliable enough if (initial && initial === location.href) { initial = null; return; } SimpleHistory.notify(event.state || {}); }, false); } }; }(window));
参考阅读:
- 原生JS实现一个简单的前端路由(路由实现的原理)
- 从 React Router 谈谈路由的那些事
相关文章推荐
- JS原生一步步实现前端路由和单页面应用
- 百度前端笔试题目--css 实现一个带尖角的正方形
- 京东2017实习校招笔试题目-异或实现
- 利用HTML5,前端js实现图片压缩
- 用html5 js实现点击一个按钮达到浏览器全屏效果
- JS实现的一个验证码,可以在前端验证后在提交action
- 利用HTML5,前端js实现图片压缩
- 【前端性能】必须要掌握的原生JS实现JQuery
- 最新阿里巴巴2014校招研发笔试题目回忆
- PhoneGap或者Cordova框架下实现Html5中JS调用Android原生代码
- js+html+css实现简单页面交互功能(2015知乎前端笔试题)http://v.youku.com/v_show/id_XMTI0ODQ5NTAyOA==.html?from=y1.7-1.2
- ××校招:前端线上笔试题--页面中的一个元素(10px*10px)围绕坐标(200, 300) 做圆周运动
- 2014.3.29 阿里巴巴 实习校招 笔试 题目及部分参考答案
- 9月10日,美团网2014校招研发笔试哈尔滨站 1、链表翻转。给出一个链表和一个数k,比如链表1→2→3→4→5→6,k=2,则翻转后2→1→4→3→6→5,若k=3,翻转后3→2→1→6→5→4,若k=4,翻转后4→3→2→1→5→6,用程序实现
- 一个拓扑结构题得实现(2011baidu校招研发部门的面试题目)
- 创建一个js日历(原生JS实现日历)
- PhoneGap或者Cordova框架下实现Html5中JS调用Android原生代码
- 用html5 js实现点击一个按钮达到浏览器全屏效果
- 2014.3.29 阿里巴巴 实习校招 笔试 题目及部分参考答案
- director.js实现前端路由使用实例