如上標題所述,ace admin做后台頁面的時候,可以實現類似於用freamset的功能,但是ace admin做的比freamset更好,他可以用異步加載的形式展示,而加載的頁面的內容可以盡可能的少(或者說按需加載)。
這個主要是使用了pjax的功能,pjax的實現原理如下:
history API中有幾個新特性,分別是history.pushState和history.replaceState,我們把pushState+AJAX進行封裝,合起來簡單點叫,就是PJAX~ 雖說實現技術上沒什么新東西,但是概念上還是有所不同的。
PJAX的基本思路是,用戶點擊一個鏈接,通過ajax更新頁面變化的部分,然后使用HTML5的pushState修改瀏覽器的URL地址,這樣有效地避免了整個頁面的重新加載。如果瀏覽器不支持history的兩個新API或者JS被禁用了,那這個鏈接就只能跳轉並重新刷新整個頁面了。和傳統的ajax設計稍微不同,ajax通常是從后台獲取JSON數據,然后由前端解析渲染,而PJAX請求的是一個在服務器上生成好的HTML碎片
引用至:http://www.cnblogs.com/hustskyking/p/history-api-in-html5.html
因為有pjax的支持,我們可以異步加載頁面的時候,頁面的標題、歷史信息都可以更新,當我們再次刷新頁面的時候回出現在當前頁面,直接點擊瀏覽器上的后退按鈕可以回到上一個界面。
話題扯得有點遠,回到ace admin。
還是按照項目來說吧,我最近的接收的項目,是一個統計項目,相當於后台管理,而每一個很多現實在瀏覽器的url,都是這樣的:http://localhost:8080/analytics/main#bizReport?type=L&functionId=140101,我一下子又一點懵逼,url里帶“#”,好吧,百度一下就知道了,10年9月,twitter改版。開始正式使用這樣的url,然后就變成的流行。詳情請見http://www.cnblogs.com/kaituorensheng/p/3776527.html。
當然使用#號,也沒有打不了,我們寫js的時候,經常寫回到頂部的時候,會用這個“#”+一個頁面頂部的元素的id,實現定位跳轉。但是我的項目是使用springmvc,url restful編碼的啊,加“#”是幾個意思?而且項目還能夠正常的跳轉和使用,最糟糕的是,我竟然在百度上沒有找到詳細所以說明原理的地方,公司的前輩說自己要獨立思考(不是一般要學會問問題么?)負責我這個項目的人在我入職之前離職了,等於說我現在能夠解惑的人都找不到,坑死爹了。
在百度上說這個頁面使用了pajx,jquery有一個插件,專門寫pajx的,叫jquery.pjax.js,我在想我的項目里是不是也有這個文件,然后去找,沒有找到啊,有木有!
我的項目前端是使用的ace admin框架,所以就可能出現在這里,在我的模板頁里找到了如下代碼:
<script type="text/javascript"> jQuery(function($) { //Load content via ajax if ('enable_ajax_content' in ace) { var options = { content_url : function(url) { return url; }, default_url : 'dashboard' //default url }; ace.enable_ajax_content($, options); } }); </script>
So,我的代碼在點擊目錄的時候,調用了ace.enable_ajax_content($, options);這一個函數,函數是在刷新是加載的,而點擊的時候后點擊事件。Ok,找到了函數,在我的ace. ajax_content.js里剛好有這個函數:
ace.enable_ajax_content = function($, options) {
//var has_history = 'history' in window && typeof window.history.pushState === 'function';
var content_url = options.content_url || false
var default_url = options.default_url || false;
var loading_icon = options.loading_icon || 'fa-spinner fa-2x orange';
var loading_text = options.loading_text || '';
var update_breadcrumbs = options.update_breadcrumbs || typeof options.update_breadcrumbs === 'undefined';
var update_title = options.update_title || typeof options.update_title === 'undefined';
var update_active = options.update_active || typeof options.update_active === 'undefined';
var close_active = options.close_active || typeof options.close_active === 'undefined';
$(window)
.off('hashchange.ajax')
.on('hashchange.ajax', function(e, manual_trigger) {
var hash = $.trim(window.location.hash);
if(!hash || hash.length == 0) return;
hash = hash.replace(/^(\#\!)?\#/, '');
var url = false;
if(typeof content_url === 'function') url = content_url(hash);
if(typeof url === 'string') getUrl(url, hash, manual_trigger || false);
}).trigger('hashchange.ajax', [true]);
/**
if(has_history) {
window.onpopstate = function(event) {
JSON.stringify(event.state);
//getUrl(event.state.url, event.state.hash, true);
}
}
*/
if(default_url && window.location.hash == '') window.location.hash = default_url;
function getUrl(url, hash, manual_trigger) {
var event
$(document).trigger(event = $.Event('ajaxloadstart'), {url: url, hash: hash})
if (event.isDefaultPrevented()) return;
var contentArea = $('.page-content-area');
contentArea
.css('opacity', 0.25)
var loader = $('<div style="position: fixed; z-index: 2000;" class="ajax-loading-overlay"><i class="ajax-loading-icon fa fa-spin '+loading_icon+'"></i> '+loading_text+'</div>').insertBefore(contentArea);
var offset = contentArea.offset();
loader.css({top: offset.top, left: offset.left})
$.ajax({
'url': url
})
.complete(function() {
contentArea.css('opacity', 0.8)
$(document).on('ajaxscriptsloaded', function() {
contentArea.css('opacity', 1)
contentArea.prevAll('.ajax-loading-overlay').remove();
});
})
.error(function() {
$(document).trigger('ajaxloaderror', {url: url, hash: hash});
})
.done(function(result) {
$(document).trigger('ajaxloaddone', {url: url, hash: hash});
var link_element = $('a[data-url="'+hash+'"]');
var link_text = '';
if(link_element.length > 0) {
var nav = link_element.closest('.nav');
if(nav.length > 0) {
if(update_active) {
nav.find('.active').each(function(){
var $class = 'active';
if( $(this).hasClass('hover') || close_active ) $class += ' open';
$(this).removeClass($class);
if(close_active) {
$(this).find(' > .submenu').css('display', '');
//var sub = $(this).find(' > .submenu').get(0);
//if(sub) ace.submenu.hide(sub, 200)
}
})
link_element.closest('li').addClass('active').parents('.nav li').addClass('active open');
if('sidebar_scroll' in ace.helper) {
ace.helper.sidebar_scroll.reset();
//first time only
if(manual_trigger) ace.helper.sidebar_scroll.scroll_to_active();
}
}
if(update_breadcrumbs) {
link_text = updateBreadcrumbs(link_element);
}
}
}
//convert "title" and "link" tags to "div" tags for later processing
result = String(result)
.replace(/<(title|link)([\s\>])/gi,'<div class="hidden ajax-append-$1"$2')
.replace(/<\/(title|link)\>/gi,'</div>')
contentArea.empty().html(result);
contentArea.css('opacity', 0.6);
//remove previous stylesheets inserted via ajax
setTimeout(function() {
$('head').find('link.ajax-stylesheet').remove();
var ace_style = $('head').find('link#main-ace-style');
contentArea.find('.ajax-append-link').each(function(e) {
var $link = $(this);
if ( $link.attr('href') ) {
var new_link = jQuery('<link />', {type : 'text/css', rel: 'stylesheet', 'class': 'ajax-stylesheet'})
if( ace_style.length > 0 ) new_link.insertBefore(ace_style);
else new_link.appendTo('head');
new_link.attr('href', $link.attr('href'));//we set "href" after insertion, for IE to work
}
$link.remove();
})
}, 10);
//////////////////////
if(update_title) updateTitle(link_text, contentArea);
if( !manual_trigger ) {
$('html,body').animate({scrollTop: 0}, 250);
}
//////////////////////
$(document).trigger('ajaxloadcomplete', {url: url, hash: hash});
})
}
}
var contentArea = $('.page-content-area');
contentArea
.css('opacity', 0.25)
var loader = $('<div style="position: fixed; z-index: 2000;" class="ajax-loading-overlay"><i class="ajax-loading-icon fa fa-spin '+loading_icon+'"></i> '+loading_text+'</div>').insertBefore(contentArea);
var offset = contentArea.offset();
loader.css({top: offset.top, left: offset.left})
這一處代碼,實現在原始的頁面上加一個層,並顯示一個旋轉的加載按鈕。
$.ajax({
'url': url
})
之后的代碼就是異步加載你想要加載的頁面。
contentArea.empty().html(result);
這一行,就是替換之前的頁面里的內容。
var contentArea = $('.page-content-area');就是你的頁面的主體部分,也就是需要異步更新的部分。
其實我並不是做前端的,只是有一點興趣,如果這篇文章有什么漏洞和缺陷,歡迎批評指正,謝謝!!!
