- 浏览: 1432933 次
- 性别:
- 来自: 上海
文章分类
最新评论
-
luhouxiang:
写的很不错,学习了
Extjs 模块化动态加载js实践 -
kingkongtown:
如果想改成淘宝后台那样,可以在编辑器批量上传图片呢?
kissy editor 阶段体会 -
317966578:
兄弟我最近也在整jquery和caja 开放一些接口。在git ...
caja 原理 : 前端 -
liuweihug:
Javascript引擎单线程机制及setTimeout执行原 ...
setTimeout ,xhr,event 线程问题 -
辽主临轩:
怎么能让浏览器不进入 文档模式的quirks模式,进入标准的
浏览器模式与文本模式
研究 gmail 有感
理论:
历史:
最早没有 xhr 的时候,要想得到无刷新的用户体验,唯一的方法就是隐藏帧技术(frame) ,发展到现在的 iframe,这个技术仍然有它的使用场景,即在文件上传以及 简单情况下浏览器的前进后退导航功能 上。
使用:
当一个页面嵌入一个iframe时,当javascript变动iframe的src(或者操作document open 与 close),会在浏览器上生成一条历史记录,点击后退的话,主页面没有变化,但是iframe会加载历史记录中的上一条src(或者文档),因此可以解决传统用户体验的浏览器导航部分。
适用范围:
一般用于界面切换,当界面有大的变化,且没有修改或删除操作时 ,可以由用户点击浏览器的返回操作来达到上一个操作界面。
技术描述:(firefox 适用,ie不适用)
主页面 javascript 设置里面的 iframe 的 src (向服务器传递信息),当iframe 加载完毕后,在iframe的页面调用主页面的回调函数,达到更新主页面的作用,并向浏览器添加一条历史记录。当用户点击后退后,iframe会加载历史记录的上一条页面,重新调用上一个页面所应该的主页面callback,修改主页面到上一个功能界面,达到是主页面回退的效果. iframe 一般是设置样式 display:none,排除在文档流中,不参与用户界面。
示例 (firefox 适用):
主页面 :index.html
<iframe id='i' style='display:none'></iframe> <div id='d'></div> <div id='d2'></div> <input type='button' onclick='bclick();' value='change'/> <script> var ii=0; function callback(str){ //alert(ii); document.getElementById('d').innerHTML='iframe call back :'+str; } function bclick() { document.getElementById('d2').innerHTML='mimic ajax '+ii; document.getElementById('i').src='iframe.html?i='+(ii++); } window.onload=function(){ document.getElementById('i').src='iframe.html'; } </script>
隐藏帧页面 :iframe.html
<script> window.onload=function(){ parent.callback(window.location); } </script>
实战(多浏览器解决方案)
根据 advanced dom scripting 以及 YUI YAHOO.util.History 提出的方案,可以解决浏览器导航问题以及书签功能。
对于 firefox,ie8 可以直接给url添加 hash ,则firefox,ie8会把变动的 url加到浏览器history中,而ie6,7 则不会。
firefox
每次操作添加 hash 到 url,并后台 setInterval 监控 url hash 的变化,根据当前的hash 进行 ajax 操作,( 用户点击后退只会改变hash值。 )
updated 2010-12-29 :
firefox chrome 已经支持 hashchange 事件,不再需要定时器监控了,监听事件即可。
ie 6,7
设置隐藏的iframe,每次操作用脚本设置iframe的内容 (注意:如果仅仅设置 src 参数 ?x=xx 不同,ie6,7 并不会产生历史纪录,必须src不同,直接脚本产生 iframe 新document(open,write,close)也可以产生历史纪录),将当前hash 插入到生成的iframe内容中,后台监控 setInterval iframe 内容中 hash 的变化,如果变化( 用户点击后退会使当前页面iframe的内容变化 ),则提取hash值,添加到主页面url,执行相关ajax 操作。
YUI BHM 相关操作:
/** * Update the IFrame with our new state. * * @method _updateIFrame * @private * @return {boolean} true if successful. false otherwise. */ function _updateIFrame (fqstate) { var html, doc; html = '<html><body><div id="state">' + fqstate + '</div></body></html>'; try { doc = _histFrame.contentWindow.document; doc.open(); doc.write(html); doc.close(); return true; } catch (e) { return false; } }
关键是 open() ,close() 会增加历史 ,之后可以将数据附在 doc 上,后退的话数据就会回来,但是注意 close() 后会触发 iframe load 事件,yui3 采用 hash 来存储数据:
HistoryHash._updateIframe = function (hash, replace) { var iframeDoc = iframe.contentWindow.document, iframeLocation = iframeDoc.location; iframeDoc.open().close(); if (replace) { iframeLocation.replace(hash.charAt(0) === '#' ? hash : '#' + hash); } else { iframeLocation.hash = hash; } };
ie8
很简单,由于有相关事件直接监控 Hash 变动即可 ,不用像firefox一样轮循查看 :
if (YAHOO.env.ua.ie) { if (typeof document.documentMode === "undefined" || document.documentMode < 8) { // IE < 8 or IE8 in quirks mode or IE7 standards mode //利用 iframe 来生成历史纪录 _checkIframeLoaded(); } else { // IE8 in IE8 standards mode //直接利用特有事件 YAHOO.util.Event.on(top, "hashchange", function () { var hash = _getHash(); _handleFQStateChange(hash); _storeStates(); }); _initialized = true; YAHOO.util.History.onLoadEvent.fire(); } } else { //其他浏览器,轮训hash值变化 // Start the thread that will have the responsibility to // periodically check whether a navigate operation has been // requested on the main window. This will happen when // YAHOO.util.History.navigate has been called or after // the user has hit the back/forward button. // On Safari 1.x and 2.0, the only way to catch a back/forward // operation is to watch history.length... We basically exploit // what I consider to be a bug (history.length is not supposed // to change when going back/forward in the history...) This is // why, in the following thread, we first compare the hash, // because the hash thing will be fixed in the next major // version of Safari. So even if they fix the history.length // bug, all this will still work! counter = history.length; // On Gecko and Opera, we just need to watch the hash... hash = _getHash(); setInterval(function () { var state, newHash, newCounter; newHash = _getHash(); newCounter = history.length; if (newHash !== hash) { hash = newHash; counter = newCounter; _handleFQStateChange(hash); _storeStates(); } else if (newCounter !== counter && YAHOO.env.ua.webkit) { hash = newHash; counter = newCounter; state = _fqstates[counter - 1]; _handleFQStateChange(state); _storeStates(); } }, 50);
书签问题:
多个浏览器都可以通过,添加书签附带了当前页面的hash值。载入书签时,首先读取Hash值进入相应的ajax操作。
demo:
updated : 2010-12-29
由于 ie>7 以及 firefox ,chrome 都已经支持 hashchange 事件以及历史存储,那么实际上难点就是 ie6,7 下使用 iframe 来记录导航历史 :
simple hashchange for ie6,7 @ google code
kissy 采用先进的事件补丁技术优雅地解决了这个问题 ,在任何浏览器下都可以直接 :
function t() { alert("current hash :" + window.location.hash); } KISSY.Event.on(window, "hashchange", t);
即可 !
PS:html5 提出了新的标准 ,目前 chrome 下已经实现:
session history and navigation
github 也做了尝试:
how to rewrite url without refresh like github
PS2: 如果不想使得修改 hash 而引起浏览器增加历史记录,可使用 location.replace('#xx') ,对于 ie6,7 模拟的iframe,情况则只需要只修改 body 的 innerHtml :
iframe.contentWindow.document.body.innerHTML='#xx'
发表评论
-
continuation, cps
2013-09-12 16:49 2712起 随着 nodejs 的兴起,异步编程成为一种潮流 ... -
一种基于匹配回朔的 css3 选择器引擎实现
2013-05-07 20:40 3345一种基于匹配回朔的 css3 选择器引擎实现 介绍 C ... -
cubic-bezier 模拟实现
2013-01-05 16:34 14014cubic-bezier 曲线是 css3 动画的一个重要基石 ... -
构建前端 DSL
2012-10-11 22:10 5282目前在传统的软件开 ... -
Get cursor position and coordinates from textarea
2012-04-10 20:50 4924最近需要从 textarea 中获 ... -
兼容 ie 的 transform
2012-02-23 14:00 6331css 2d transform 是 css3 引入的一个新的 ... -
promise api 与应用场景
2012-02-07 17:34 7284promise 是 commonjs 社区中提出的异步规范,其 ... -
closure compiler 代码优化实例
2012-01-08 03:23 2768closure compiler 可以进行不少有意思的优化 ... -
write html parser
2011-12-01 02:48 2846首先需要声明 html 不能用正则表达式来直接匹配进行内容抽取 ... -
获取剪贴板数据
2011-11-07 23:31 6377兼容性: 获取剪贴板数据这块各个浏览器间存在很大的 ... -
url 映射问题
2011-11-07 21:52 3162背景 url mapping 我最早知道是作为 j ... -
tip:如何原生播放声音
2011-10-19 12:45 2894如果不想考虑浏览器间 ... -
转载:瀑布流布局浅析
2011-09-29 19:02 2784简介 如果你经 ... -
cross domain request
2011-09-29 18:39 2787场景 跨域请求是随着 ... -
基于多继承的树设计
2011-09-18 03:42 2199分类 树是一种常见 ... -
caja 原理 : 前端
2011-09-01 16:48 6937作为前端开放的基础安全保证,caja 是目前比较合 ... -
tokenization of html
2011-08-29 22:38 2675html 符号解析问题 场景: 在页面上输出包 ... -
ie 下 cloneNode 导致的属性克隆
2011-08-24 16:10 2409这个还是很值得记下,一直存在的很大隐患终于解决,由于在 ie& ... -
循环引用下的深度克隆
2011-08-04 20:39 2230深度复制和浅度复制 是当初初学 c 遇到的第一批问题,似乎使 ... -
模块的静态与动态循环依赖
2011-07-25 03:43 3193场景: 循环依赖 我是不支持的,但现实中似乎又确实需 ...
相关推荐
一个用于通过XHR2在浏览器上预加载资源的1kb JavaScript库。它提供了加载不同文件类型的资产和合成进度事件的功能
XHR Proxy Tool chrome浏览器插件 可以用于跨域接口请求 另外nei平台管理接口也指定使用该插件(https://nei.netease.com)
浏览器不兼容问题解决方案[归类].pdf
浏览器兼容性问题及解决方案[归类].pdf
叶子浏览器,基于Cef,访问网页时自动抓取结构化xhr数据
MSC所有软件安装MSC.License冲突终极解决方案[文].pdf
详细介绍了使用ajax如何兼容各种浏览器
MSC所有软件安装MSC.License冲突终极解决方案参照.pdf
XHR 博文链接:https://eric2007.iteye.com/blog/213570
自动化模拟浏览器,打开网站,分析所有ajax / XHR请求,包含详细的response request数据。。。就是F12以后Network中xhr显示的数据。。。 采用python browsermobproxy selenium实现 包含代码,chromedriver 、 ...
xr 是 XMLHttpRequest 的超简单封装,并返回 ES6 Promise。示例代码:xr.get('/api/items', {take: 5}) ... console.log("xhr", xhr); console.log("progress", xhrProgressEvent); } } });
自己封的XHR,实现JAVA与JS直接通信,起到连接JAVA与JS的桥梁,使用方法直接在JS中引入XhrAjax.js,传入参数带回返回值即可,但是要注意回调的时候要eval()激回一下返回值!
JavaScript - XHR实现短信验证码注册登录完整示例:JavaScript - XHR.js和附件说明
修改了帮助文档的index.html, 包含localXHR.js 能够在本地直接打开帮助文档!
API的一个子集这样你就可以在两个node.js中,通过使用浏览器的作品写的代码require('request')在你的代码,并告诉您的浏览器捆绑到加载xhr而不是request 。 对于browserify,将一个字段添加到package.json : ...
海量数据库解决方案[汇编].pdf
一个js脚本. 需要的人自然知道它是干什么的,呵呵 共享给需要的人
IPv6解决方案_双栈+NAT技术白皮书V102.pdf
【AngularJS入门教程05:XHR和依赖注入】 很多AngularJS初学者看到中文入门教程,却无法使用GitHub下载到配套的Angular的Seed工程,因此学习曲线大。在此专门下载配套工程打包分享给大家。 本集教程地址: ...
工作室交流会的ppt,具体是讲通过动态修改html来借用浏览器的实时渲染特性来实现资源的异步下载以及一些应用。