Ace admin 如何实现类似于freamset加载页面
如上标题所述,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');就是你的页面的主体部分,也就是需要异步更新的部分。
其实我并不是做前端的,只是有一点兴趣,如果这篇文章有什么漏洞和缺陷,欢迎批评指正,谢谢!!!
Ace admin 如何实现类似于freamset加载页面的更多相关文章
- webclient 比浏览器加载页面慢的一个问题
测试中发现webclient 比浏览器加载页面慢的一个问题:原因WebClient 支持 gzip, deflate,但是未设置 解决方案: class WebClientEx : WebClient ...
- RadioGroup+Fragment 使用Fragment的add()方法,防止使用replace每次都重新加载页面,造成资源浪费
radiogroup+fragment是很常用的主页导航控件,之前为了代码简便一直使用的replace()替换fragment,代码如下: getSupportFragmentManager().be ...
- jquery加载页面的方法
jquery加载页面的方法(页面加载完成就执行),建议大家看下windows.onload与$(document).ready之间的区别. 1.$(function(){ $("#a&q ...
- 爬虫再探实战(三)———爬取动态加载页面——selenium
自学python爬虫也快半年了,在目前看来,我面临着三个待解决的爬虫技术方面的问题:动态加载,多线程并发抓取,模拟登陆.目前正在不断学习相关知识.下面简单写一下用selenium处理动态加载页面相关的 ...
- jquery加载页面的方法(页面加载完成就执行)
jquery加载页面的方法(页面加载完成就执行),建议大家看下windows.onload与$(document).ready之间的区别. 1.$(function(){ $("#a&qu ...
- ExtJs非Iframe框架加载页面实现
在用Ext开发App应用时,一般的框架都是左边为菜单栏,中间为tab页方式的显示区域.而tab页面大多采用的嵌入一个iframe来显示内容.但是采用iframe方式有一个很大的弊端就是每次在加载一个新 ...
- 加载页面遮挡耗时操作任务页面--第三方开源--AndroidProgressLayout
在Android的开发中,往往有这种需求,比如一个耗时的操作,联网获取网络图片.内容,数据库耗时读写等等,在此耗时操作过程中,开发者也许不希望用户再进行其他操作(其他操作可能会引起逻辑混乱),而此时需 ...
- 关于IE8中使用Jquery load方法无法正常加载页面
最近发现,在IE8中使用Jquery load方法时无法正常加载页面,页面显示空白,没有加载.调试发现,页面多了一个</div>标签,但在FF和CH下表现正常.希望能给遇到同样问题的码农有 ...
- jQuery EasyUI动态添加控件或者ajax加载页面后不能自动渲染问题的解决方法
博客分类: jquery-easyui jQueryAjax框架HTML 现象: AJAX返回的html无法做到自动渲染为EasyUI的样式.比如:class="easyui-layout ...
随机推荐
- Android捕捉图像后在SurfaceView上变形显示问题的处理
我们在Android中经常会使用SurfaceView编写自定义的摄像头,可是有的时候会经常会出现图像的变形,我们就会很郁闷的问这到底是为什么呢?其实这个最根本的原因是SurfaceView和PreV ...
- log4j的PatternLayout参数含义
参数 说明 例子 %c 列出logger名字空间的全称,如果加上{<层数>}表示列出从最内层算起的指定层数的名字空间 log4j配置文件参数举例 输出显示媒介 假设当前logger名字空间 ...
- Mybatis Dao开发的两种方式(一)
原始Dao的开发方式: 1.创建数据库配置文件db.properties jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localh ...
- String.Compare 方法 (String, Int32, String, Int32, Int32)
String.Compare 方法 (String, Int32, String, Int32, Int32) 对两个指定的 String 对象的子字符串进行比较,并返回一个指示二者在排序顺序中的相对 ...
- 一:SpringMVC架构流程
架构流程: 1.用户发送请求至前端控制器DispatcherServlet 2.DispatcherServlet收到请求调用HandlerMapping处理器映射器. 3.处理器映射器根据请求url ...
- java_对象序列化、反序列化
1.概念 序列化:将对象转化为字节序列的过程 反序列化:将字节序列转化为对象的过程 用途: A:将对象转化为字节序列保存在硬盘上,如文件中,如文本中的例子就是将person对象序列化成字节序列,存在p ...
- my docker note
环境: docker1.10.3 #hello docker docker run --name myhello docker.io/centos:67591570dd29 /bin/echo 'he ...
- Cardinality Estimation算法学习(一)(了解基数计算的基本概念及回顾求字符串中不重复元素的个数的问题)
最近在菜鸟教程上自学redis.看到Redis HyperLogLog的时候,对“基数”以及其它一些没接触过(或者是忘了)的东西产生了好奇. 于是就去搜了“HyperLogLog”,从而引出了Card ...
- Docker问题集合
1. 安装后启动出现 解决办法: 删除以下文件夹重新启动docker服务即可: 可能原因:(1) 之前docker进程出现错误并保存在keys.json文件中 (2) 删除之前配置了阿里云镜像,生成了 ...
- 小白学flask之hello,world
from flask import Flask app = Flask(__name__) @app.route("/") def hello(): return "He ...