需求

(1)支持iframe、html、json格式的tab内容远程请求

(2)支持动态添加tab

(3)支持远程加载完成监听,支持tab激活事件监听

(4)支持reload tab内容【如果是远程加载】

(5)支持邮件菜单【未实现】

实现图例

客户代码

 <body>
<div id="text">
<h3>无题</h3>
<p>月落湖面两清影,</p>
<p>岸柳丝丝弄轻盈。</p>
<p>此番凉意写不出,</p>
<p>难画秋月一片晴。</p> </div>
<div style="padding-left:100px; padding-bottom:12px;">
<div id="tabContainer" style="width:800px;height:260px">
<div title="静态html" closable="true" >项目1项目1项目1项目1项目1项目1项目1项目1项目1项目1项目1项目1项目1项目1项目1项目1项目1项目1项目1项目1项目1</div>
<div title="iframe加载" isiframe="true" url="/innerpage.html" iconcls="icon-edit" closable="true">
</div>
<div title="远程HTML加载" dataType="html" url="/content.html" iconcls="icon-save" closable="true">
</div>
</div>
</div>
<script type="text/javascript">
var tabs;
$(function () {
tabs = $("#tabContainer").tabs({
items: [{
title: '远程加载JSON数据',
closable: false,
iconcls: 'icon-print',
actived: true,// 激活状态
url: 'testServer/jsonQuestTest.ashx',//如果不配置采用公用 $.fn.tabs.defaults里的配置
dataType: 'json'// //如果不配置采用公用 $.fn.tabs.defaults里的配置
},{
title: '文本测试',
closable: false,
iconcls: 'icon-back',
actived: false,// 激活状态
content: $("#text") //'<a>我是测试内容.....................</a>'// 可以是文本,可以是$("#id")对象
}],
onLoadSuccess: function (title, context) {
console.log(title + "加载完成");
if (title == "远程加载JSON数据" || title == "动态添加tab") {
context.target.html(JSON.stringify(context.data));
}
},
activedHandler: function (tilte,context) {
console.log("actived=" + tilte);
},
closedHandler: function (title) {
console.log("closed=" + title);
}
});
});
function addTab() {
tabs.tabs("addTabs", {
title: '动态添加tab',
closable: true,
iconcls: 'icon-back',
actived: false,// 激活状态
//content: '<a>我是动态tab内容</a>'
url: 'testServer/jsonQuestTest.ashx',//如果不配置采用公用 $.fn.tabs.defaults里的配置
dataType: 'json',// //如果不配置采用公用 $.fn.tabs.defaults里的配置
onLoadSuccess: function (title, context) {
context.target.html(title+"loadsucc;我自己注册的事件 "+JSON.stringify(context.data));
}
});
}
function getSelectedTab() {
var res = tabs.tabs("getSelectedTab");
alert(res.titleObj.attr("title"));
}
function reload() {
var itemsopt = $("#itemsopt").children("option[selected]");
tabs.tabs("reLoadTab", itemsopt.val());
if (tabs.tabs("isExist", itemsopt.val())) {
console.log(itemsopt.val()+"exist");
} else {
console.log(itemsopt.val() + "no exist");
} }
</script>
</body>

组件代码

 /**************************************************************
*作者:hjwen
*电邮:hjwen88@126.com
*版本:1.0
*版权许可:中国通用开源许可协议V1.0
*说明:myui组件tabs组件
***************************************************************/
(function ($) {
/******
*渲染目标:renderHtml为构建html结构的函数,init初始化会调用
*******/
var contentPadding = 6;
var showTitleItem = null;
var showContentItem = null;
var itemTitleContainer, itemContentContainer, existItems;
var headerWith = 0;
var itemsWidth = 0;
var leftMoreBtn = null, rightMoreBtn = null;
function renderHtml(target, opts) {
itemContentContainer = target;
var panel = target.panel({ expandable: false, maximizable: false, closeable: false, expanded: false });
var titleWrap = target.prev("div");
headerWith = titleWrap.width();
var panelTitle = titleWrap.children(".panel-tilte");
itemTitleContainer = $("<ul class=\"tabsul\"></ul>").appendTo(panelTitle);
target.css({ "overflow": "hidden", "padding": "0px" });
existItems.css({ "width": target.width() - contentPadding * 2 + "px", "height": target.height() - contentPadding * 2 + "px", "margin": "0px", "padding": contentPadding + "px", "overflow": "auto" }).hide();
createTabs(opts.items);
existItems = null;
};
/**********私有方法开始********************/
function createTabs(items) {
$.each(items, function (i, item) {
createTab(item, i);
});
showContentItem.show();
showTitleItem.attr("actived", "true").children("a").addClass("tabs_selected").css("border-bottom", "1px solid #FFFFFF");
}
function createTab(item, index) {
//创建tab标题项
var a_tag = "<a href='javascript:void(0)'>";
if (item.iconcls != '')
a_tag = a_tag + "<span class='item_title_ioc " + item.iconcls + "'></span>";
if (item.closable)
a_tag = a_tag + "<span class='item_title_text'>" + item.title + "</span><span for=" + index + " class='item_title_close' ></span></a>";
else
a_tag = a_tag + "<span class='item_title_text'>" + item.title + "</span></a>";
var itemTitleLi = $("<li contextmenu=\"" + item.contextMenu + "\" datatype=\"" + item.dataType + "\" url=\"" + item.url + "\" isiframe=\"" + item.isiframe + "\" title=\"" + item.title + "\" closable=\"" + item.closable + "\" actived=\"" + item.actived + "\" for=" + index + ">" + a_tag + "</li>").appendTo(itemTitleContainer);
itemTitleLi.bind({
"click": function () {
var $this = $(this);
if ($this.attr("actived") == "true")
return;
var idx = $this.attr("for");
showContentItem.hide();
showTitleItem.attr("actived", "false").children("a").removeClass("tabs_selected").css("border-bottom", "1px solid #99BBE8");
$.each(itemContentContainer.children("div"), function (j, obj) {
var $obj = $(obj);
if (j == parseInt(idx)) {
$this.attr("actived", "true").children("a").addClass("tabs_selected").css("border-bottom", "1px solid #FFFFFF");
showContentItem = $obj.show();
showTitleItem = $this;
}
});
if (item.activedHandler != null) {
item.activedHandler(showTitleItem.attr("title"), { titleObj: showTitleItem, conetentObj: showContentItem });
}
}
});
//如果可以关闭
if (item.closable) {
itemTitleLi.children("a").children(".item_title_close").bind({
click: function () {
var allIts = itemContentContainer.children("div");
var $t = $(this);
var foridx = parseInt($t.attr("for"));
var removeContent = null;
for (var k = 0, len = allIts.length; k < len; ++k) {
if (foridx == k) {
removeContent = $(allIts[k]);
break;
}
};
//如果关闭的是激活的tab,则需要调整激活的tab
var showIdx = 0;
var titleLi = $t.parent("a").parent("li");
if (titleLi.attr("actived") == "true") {
var showIt = titleLi.prev("li");
showIdx = foridx - 1;
if (showIt.length == 0) {
showIt = titleLi.next("li");
showIdx = foridx + 1;
}
showTitleItem = showIt;
showTitleItem.attr("actived", "true").children("a").addClass("tabs_selected").css("border-bottom", "1px solid #FFFFFF");
//激活对应的内容div
for (var k = 0, len = allIts.length; k < len; ++k) {
if (showIdx == k) {
$(allIts[k]).show();
break;
}
};
}
//修改删除项目后面所有li项的for属性
var nextAll = titleLi.nextAll();
if (nextAll.length > 0) {
setTimeout(function () {
$.each(nextAll, function (j, obj) {
var $obj = $(obj);
var curFor = parseInt($obj.attr("for"));
var newFor = curFor - 1;
$obj.attr("for", newFor);
$obj.children("a").children(".item_title_close").attr("for", newFor);
});
}, 0);
}
var title = titleLi.attr("title");
itemsWidth = itemsWidth - titleLi.outerWidth()-11;
titleLi.remove();
removeContent.remove();
showMoreBtn();
if (item.closedHandler != null)
item.closedHandler(title);
},
mouseover: function () {
$(this).css("background-color", "#8DE2B3");
},
mouseout: function () {
$(this).attr("style", "");
}
});
}
var contentDiv;
if (item.exist) {//已经存在的不用再创建内容div
contentDiv = $(existItems[index]);
} else {
contentDiv = $("<div></div>").appendTo(itemContentContainer).css({ "width": itemContentContainer.width() - contentPadding * 2 + "px", "height": itemContentContainer.height() - contentPadding * 2 + "px", "margin": "0px", "padding": contentPadding + "px", "overflow": "auto" }).hide();;
}
if (item.content != "") {//优先取content
if ($.isPlainObject(item.content)) {
item.content.remove().appendTo(contentDiv);
} else {
contentDiv.html(item.content);
}
} else {
//是否有url 远程加载
if (item.url != "") {
load(contentDiv, item,false);
}
}
if (index == 0) {//默认第一个为激活状态
showTitleItem = itemTitleLi;
showContentItem = contentDiv;
}
if (item.actived) {
showTitleItem = itemTitleLi;
showContentItem = contentDiv;
}
itemsWidth = itemsWidth + itemTitleLi.outerWidth()+11;
showMoreBtn();
};
function load(target,item,isReload) {
if (item.isiframe) {
target.css({ "overflow": "hidden", "padding": "0", "width": target.width() + contentPadding * 2 + "px", "height": target.height() + contentPadding * 2 + "px" });
var loading = $("<div class='loading icon-loading'>正在加载......</div>").appendTo(target);
var iframe;
if (isReload) {
iframe = target.children("iframe")[0];
iframe.contentWindow.location.reload();
} else {
iframe = $("<iframe title='" + item.title + "' frameborder='0' style='overflow:visible' scrolling='auto' width='100%' height='100%' src='" + item.url + "' ></iframe>").appendTo(target);
iframe.load(function () {
loading.remove();
if (item.onLoadSuccess != null)
item.onLoadSuccess($(this).attr('title'), target);
});
}
} else {
if (item.dataType == "json") {
var ajaxopt = {
url: item.url,
loadingContainer: target,
returnParams: true,
params: { title: encodeURIComponent(item.title) }
};
if (item.onLoadSuccess != null)
ajaxopt.okdeal = function (data, extParams) {
item.onLoadSuccess(decodeURIComponent(extParams.title), { data: data, target: target });
};
$.myui.ajaxRequest(ajaxopt);
} else {
var settings = { url: item.url, extParam: item.title };
if (item.onLoadSuccess != null)
settings.loaded = function (t, extParam) {
item.onLoadSuccess(extParam, t);
};
$.myui.objectLoadContect({
target: target,
settings: settings
});
}
}
};
function showMoreBtn() {
if (itemsWidth > headerWith) {
itemTitleContainer.css("padding-left","9px");
if (leftMoreBtn == null) {
var headerWrap = itemTitleContainer.parent("div").parent("div");
leftMoreBtn = $("<a class='leftMoreBtn'></a>").appendTo(headerWrap);
rightMoreBtn = $("<a class='rightMoreBtn'></a>").appendTo(headerWrap);
leftMoreBtn.bind('click', function () {
var position = itemTitleContainer.position();
if (position.left < 9) {
var pos = position.left +80;
itemTitleContainer.animate({ left: pos },500);
}
});
rightMoreBtn.bind('click', function () {
var position = itemTitleContainer.position();
var pos = position.left -80;
itemTitleContainer.animate({ left: pos},500);
});
} else {
leftMoreBtn.show();
rightMoreBtn.show();
}
var diff = itemsWidth - headerWith;
itemTitleContainer.animate({ left: -diff }, 500);
} else {
if (leftMoreBtn != null) {
itemTitleContainer.css("padding-left", "0px");
leftMoreBtn.hide();
rightMoreBtn.hide();
var position = itemTitleContainer.position();
if (position.left < 0) {
itemTitleContainer.animate({ left: 0 }, 500);
}
}
}
}
/**********私有方法结束*******************/
/*****************************************************************************
*对外的函数统一封装到methods中
*调用方式:$.pluginInstance.pluginName("methodName",params)
******************************************************************************/
var methods = {
init: function (options) {
return this.each(function () {
var $this = $(this);
var settings
if (typeof options == 'undefined')
settings = $.fn.tabs.defaults;
else
settings = $.extend({}, $.fn.tabs.defaults, options);
var newItemArr = [];
existItems = $this.children("div");//已经存在的item项
if (existItems.length > 0) {
$.each(existItems, function (i, it) {
var $it = $(it);
newItemArr.push({
title: $it.attr("title"),
content: '',
contextMenu: false,
closable: $it.attr("closable") == "true" ? true : false,
iconcls: $it.attr("iconcls") == undefined ? "" : $it.attr("iconcls"),
actived: $it.attr("actived") == "true" ? true : false,// 激活状态
isiframe: $it.attr("isiframe") == "true" ? true : false,//如果不配置采用公用 $.fn.tabs.defaults里的配置
url: $it.attr("url") == undefined ? "" : $it.attr("url"),//如果不配置采用公用 $.fn.tabs.defaults里的配置
dataType: $it.attr("dataType") == undefined ? "json" : $it.attr("dataType"), //如果不配置采用公用 $.fn.tabs.defaults里的配置
exist: true, //
onLoadSuccess: settings.onLoadSuccess,//fn(tabtitle,resdata)
activedHandler: settings.activedHandler,//fn(tabtitle,context)
closedHandler: settings.closedHandler //fn(tabtitle) tab被关闭时触发
});
});
}
//合并每一个tab项的默认设置
$.each(settings.items, function (i, item) {
var newIt = $.extend({}, $.fn.tabs.itemdefaults, item);
newIt.exist = false;
if (typeof newIt.onLoadSuccess!='function')
newIt.onLoadSuccess = settings.onLoadSuccess;//fn(tabtitle,resdata)
if (typeof newIt.activedHandler != 'function')
newIt.activedHandler = settings.activedHandler;//fn(tabtitle,context)
if (typeof newIt.closedHandler != 'function')
newIt.closedHandler = settings.closedHandler; //fn(tabtitle) tab被关闭时触发
newItemArr.push(newIt);
});
settings.items = newItemArr;
//创建ui布局
renderHtml($this, settings);
if ($.myui.isDebug) {
$.myui.log("jQuery.tabs init finish......");
}
$this.data('settings', settings);
});
},
destroy: function (options) {
return $(this).each(function () {
var $this = $(this);
$this.removeData('settings');
});
},
/***
*opt={
title: 'tab标题',
closable: false,
iconcls: '',
actived: false,// 激活状态
isiframe: false,//如果不配置采用公用 $.fn.tabs.defaults里的配置
url: '',//如果不配置采用公用 $.fn.tabs.defaults里的配置
content: '',//内容默认为空,如果该属性有值,则优先默认采用这个,即使设置url也不会去远程加载数据,content可以是html对象,也可以是文本
dataType: 'json',// //如果不配置采用公用 $.fn.tabs.defaults里的配置
contextMenu: false //右键菜单未实现
}
***/
addTabs: function (opts) {
var newOpt = $.extend({}, $.fn.tabs.itemdefaults, opts);
newOpt.actived = true;
return $(this).each(function () {
var $this = $(this);
var settings = $this.data('settings');
if (showContentItem != null)
showContentItem.hide();
if (showTitleItem != null)
showTitleItem.attr("actived", "false").children("a").removeClass("tabs_selected").css("border-bottom", "1px solid #99BBE8");
itemContentContainer = $this;
var index = $this.children("div").length;
if (typeof newOpt.onLoadSuccess != 'function')
newOpt.onLoadSuccess = settings.onLoadSuccess;//fn(tabtitle,resdata)
if (typeof newOpt.activedHandler != 'function')
newOpt.activedHandler = settings.activedHandler;//fn(tabtitle,context)
if (typeof newOpt.closedHandler != 'function')
newOpt.closedHandler = settings.closedHandler; //fn(tabtitle) tab被关闭时触发
createTab(newOpt, index);
showContentItem.show();
showTitleItem.attr("actived", "true").children("a").addClass("tabs_selected").css("border-bottom", "1px solid #FFFFFF");
});
},
/**
* 获取选中的tab,返回值{titleObj:...,contentObj:...}
***/
getSelectedTab: function () {
return { titleObj: showTitleItem, contentObj: showContentItem };
},
/***
*重新加载某个tab,以title为标准
****/
reLoadTab: function (title) {
var $this = $(this);
var titlelis = $this.prev().children(".panel-tilte").children("ul").children();
var forIdx = -1;
var url = '';
var isIframe = false;
var dataType = "html";
var currShowTitle = null;
for (var i = 0, len = titlelis.length; i < len; ++i) {
var $li = $(titlelis[i]);
if ($li.attr("title") == title && $li.attr("url") != undefined && $li.attr("url")!='') {
forIdx = i;
url = $li.attr("url");
if ($li.attr("isiframe") != undefined) {
isIframe = $li.attr("isiframe") == 'true';
}
if ($li.attr("datatype") != undefined) {
dataType = $li.attr("datatype");
}
currShowTitle = $li;
break;
}
}
if (forIdx != -1) {
var childs = $this.children();
var updateContent = null;
for (var i = 0, len = childs.length; i < len;++i){
if (i == forIdx) {
updateContent = $(childs[i]);
}
}
if (updateContent != null) {
var opts = $this.data('settings');
var it;
for (var j = 0, len = opts.items.length; j < len;++j){
if (forIdx == j)
it = opts.items[j];
}
if (showTitleItem.attr("title") != title) {
showContentItem.hide();
showTitleItem.attr("actived", "false").children("a").removeClass("tabs_selected").css("border-bottom", "1px solid #99BBE8");
showContentItem= updateContent.show();
showTitleItem = currShowTitle.attr("actived", "true");
showTitleItem.children("a").addClass("tabs_selected").css("border-bottom", "1px solid #FFFFFF");
}
load(updateContent, it, true);
}
}
return $this;
},
/****
* 判断某个tab是否存在
****/
isExist: function (title) {
var $this = $(this);
var titlelis = $this.prev().children(".panel-tilte").children("ul").children();
var forIdx = -1;
for (var i = 0, len = titlelis.length; i < len; ++i) {
var $li = $(titlelis[i]);
if ($li.attr("title") == title && $li.attr("url") != undefined && $li.attr("url") != '') {
forIdx = i;
break;
}
}
if (forIdx > -1)
return true;
else
return false;
}
};
/********************
*组件的构造函数
*********************/
$.fn.tabs = function () {
var method = arguments[0];
if (methods[method]) {
method = methods[method];
arguments = Array.prototype.slice.call(arguments, 1);
} else if (typeof (method) == 'object' || !method) {
if ($.myui.isDebug) {
$.myui.log("jQuery.tabs init.....");
}
method = methods.init;
} else {
$.error('Method ' + method + ' does not exist on jQuery.tabs');
return this;
}
return method.apply(this, arguments);
};
/********************
*组件的默认配置值
*options={
items: [], //tab项配置,对应$.fn.tabs.itemdefaults
isiframe: false,// 是否嵌入iframe,嵌入iframe 需要与url配合使用,即采用url加载远程页面时【dataType=html】才起作用
url: '',
dataType: 'json',// json/html 远程加载时的数据格式
onLoadSuccess: null,//fn(tabtitle,resdata)
activedHandler: null,//fn(tabtitle,context)
closedHandler: null //fn(tabtitle) tab被关闭时触发
}
*********************/
$.fn.tabs.defaults = {
items: [], //tab项配置,对应$.fn.tabs.itemdefaults
isiframe: false,// 是否嵌入iframe,嵌入iframe 需要与url配合使用,即采用url加载远程页面时【dataType=html】才起作用
url: '',
dataType: 'json',// json/html 远程加载时的数据格式
onLoadSuccess: null,//fn(tabtitle,resdata)
activedHandler: null,//fn(tabtitle)
closedHandler: null //fn(tabtitle) tab被关闭时触发
};
/***
*每一个tab项目的默认配置
****/
$.fn.tabs.itemdefaults = {
title: 'tab标题',
closable: false,
iconcls: '',
actived: false,// 激活状态
isiframe: false,//如果不配置采用公用 $.fn.tabs.defaults里的配置
url: '',//如果不配置采用公用 $.fn.tabs.defaults里的配置
content: '',//内容默认为空,如果该属性有值,则优先默认采用这个,即使设置url也不会去远程加载数据,content可以是html对象,也可以是文本
dataType: 'json',// //如果不配置采用公用 $.fn.tabs.defaults里的配置
contextMenu: false //右键菜单未实现
}
})(jQuery);

我的开源框架之TAB控件的更多相关文章

  1. 开源框架之TAB控件

    我的开源框架之TAB控件   需求 (1)支持iframe.html.json格式的tab内容远程请求 (2)支持动态添加tab (3)支持远程加载完成监听,支持tab激活事件监听 (4)支持relo ...

  2. 我的开源框架之Accordion控件

    需求: (1)实现手风琴面板控件,支持静态HTML与JSON方式创建控件 (2)支持远程加载数据 (3)支持面板激活.远程加载事件注册 (4)支持动态添加.删除项目 实现图例 客户代码 <div ...

  3. Android开源的精美日历控件,热插拔设计的万能自定义UI

    Android开源的精美日历控件,热插拔设计的万能自定义UI UI框架应该逻辑与界面实现分离,该日历控件使用了热插拔的设计 ,简单几步即可实现你需要的UI效果,热插拔的思想是你提供你的实现,我提供我的 ...

  4. 网页Tab控件

    网页Tab控件 找到:http://www.open-open.com/ajax/2_Tabs.htm 页面,查看了若干Tab控件, 找到了:http://www.open-open.com/ajax ...

  5. 扩展easyUI tab控件,添加加载遮罩效果

    项目里要用HighChart显示图表,如果返回的数量量太多,生成图表是一个很耗时的过程.tab控件又没有显示遮罩的设置(至少本菜是没有找到), Google了一下,根据另一个兄台写的方法,拿来改造了一 ...

  6. NVelocity+Bootstrap tab控件 异常之

    异常信息:Encountered "tings" at line 54, column 55.Was expecting one of:   "(" ...   ...

  7. [转]几个开源的.net界面控件

    转自原文 几个不错的开源的.net界面控件,介绍几个自己觉得不错的几个开源的.net界面控件. DockPanel Suite:开发类似VS.net的界面,#Develop就是使用的这个控件. 网址: ...

  8. Android Tab控件简介

    在Android中,Tab控件是一种很常用的控件:Tab控件即标签页,可以在一页中切换显示N页内容: Tab控件具有两种实现过程,一是在同一个Activity中切换显示不同的标签页,这种主要是通过修改 ...

  9. Web端的Tab控件在切换Tab时Load数据出错的处理

    我们在应用Web端的Tab控件时,不管是Jquery easyui的还是Ext的Tab控件都会遇到一个问题,在Tab1正在加载数据的时候我们切换到Tab2,再切换回来,Load数据的控件就会出错,出错 ...

随机推荐

  1. destoon实现底部添加你是第几位访问者的方法

    经常会看到一些网站有类似“您是第位访客”字样的计数统计,这里我们来实现把这个统计功能添加到destoon的底部,显示“你是第几问访问者”的效果.此处的计数器与网站流量统计有区别,记录的是刷新次数,并不 ...

  2. 启动两个tomcat

    因为项目的种种原因,必须启动两个tomcat测试 于是复制tomcat,改端口,报错,到日志看,发现shutdow端口也需要改 总结 server.xml改两个地方的端口 <Server por ...

  3. UVA 12169 Disgruntled Judge

    我该怎么说这道题呢...说简单其实也简单,就枚举模拟,开始卡了好久,今天看到这题没a又写了遍,看似会超时的代码交上去a了,果然实践是检验真理的唯一标准... #include <iostream ...

  4. 可变参数列表-Java SE5新特性(转)

    Java1.5增加了新特性:可变参数:适用于参数个数不确定,类型确定的情况,java把可变参数当做数组处理.注意:可变参数必须位于最后一项.当可变参数个数多于一个时,必将有一个不是最后一项,所以只支持 ...

  5. linux type 命令和Linux的五个查找命令

    type命令用来显示指定命令的类型.一个命令的类型可以是如下之一 alias 别名 keyword 关键字,Shell保留字 function 函数,Shell函数 builtin 内建命令,Shel ...

  6. OpenWRT 编译 error GNU libiconv not in use but included iconv.h is from...

    OpenWRT 编译 error GNU libiconv not in use but included iconv.h is from... 编译的时候碰到一个常见的错误,但是却在一个陌生的地方爆 ...

  7. 【转】Device Tree(二):基本概念

    原文网址:http://www.wowotech.net/linux_kenrel/dt_basic_concept.html 一.前言 一些背景知识(例如:为何要引入Device Tree,这个机制 ...

  8. Smallest Rectangle Enclosing Black Pixels 解答

    Question An image is represented by a binary matrix with 0 as a white pixel and 1 as a black pixel. ...

  9. jquery插件-省市联动

        由于项目需要需要实现一个省市联动,由于业务有一些特殊的需求,使用现有的插件略有不便,就自己实现了一个.     首先需要保存地区数据的JS数据文件,我这里命名为areaData.js,内容如下 ...

  10. 漫谈linux文件IO

    在Linux 开发中,有几个关系到性能的东西,技术人员非常关注:进程,CPU,MEM,网络IO,磁盘IO.本篇文件打算详细全面,深入浅出.剖析文件IO的细节.从多个角度探索如何提高IO性能.本文尽量用 ...