首先对加载页面的地址进行判断,如果不符合要求,进行相对应的修改处理,然后使用history.pushState方法向浏览器记录(history对象)中添加一个新记录。然后通过ajax将需要的页面地址赋值给url属性,然后会返回一个来自延迟的对象的jqXHR对象,我们可以附加一个成功回调使用.done()
方法。在.done方法中实现将返回的text/html格式数据经过过滤css和js赋值给需要呈现页面(例如div)的容器中。
//result 返回的页面数据 contextArea 呈现页面的容器 result = String(result) .replace(/<(title|link|meta|script)([\s\>])/gi, '<div class="hidden ajax-append-$1"$2') .replace(/<\/(title|link|meta|script)\>/gi, '</div>') contentArea.empty().html(result);
我没有将返回的页面数据直接赋值到容器中,如果页面的数据内容包含script和css标签的话,直接将页面数据赋值到容器中后,会发送请求将这些文件加载到主页面上,如果遇到已加载的文件或者一些不必要加载的文件而不能进行过滤处理,所以先将一些不是内容的标签元素通过regex替换成带有相关标签名称样式的div,然后过滤移除加载等一系列操作。比如移除已存在的css引用文件标签,重新加载未存在的css引用文件标签:
setTimeout(function () { $('head').find('link.ajax-stylesheet').remove(); contentArea.find('.ajax-append-link').each(function (e) { var $link = $(this), t_link = $link.attr('href'); if (t_link) { if ($('head [href="' + t_link + '"]').length == 0) { var new_link = $('<link />', { type: 'text/css', rel: 'stylesheet', 'class': 'ajax-stylesheet' }) new_link.appendTo('head'); new_link.attr('href', t_link); } } $link.remove(); }); }, 10);
同样在操作js的时候也可以通过相同的原理操作处理。我们发现页面的内容发生变化了,而浏览器的地址没有发生变化,即无法实现浏览器的前进后退功能。我们需要利用ocation的hash部分和使用window.onhashchange来实现。hash是浏览器地址#后面的部分,当只有hash部分发生变化时,浏览器的历史记录会产生记录,但不会向服务器发出请求,这时按后退键地址栏的uri会变化但页面内容不变。通过window.onhashchange事件来监听hash值的更改。
$(window).off('hashchange').on('hashchange', function () { var hash = $.trim(window.location.hash); if (!hash || hash == '') { contentArea.empty(); return; } hash = hash.replace(/^(\#\!)?\#/, ''); loadHtml(hash); }).trigger('hashchange', [true]);
页面加载的时候不会触发onhashchange事件,所以在代码的最后追加了trigger() 方法。