由于jQuery ajax对Callbacks、Deferred、serialize、event等模块的依赖,建议对这些模块没有认识的朋友看一下jQuery Callbacks、jQuery Deferred、jQuery serialize、jQuery event(上)、jQuery event(下)。
这篇文章主要分析的是拥有380+行的jQuery.ajax函数,该函数是jQuery ajax的核心函数,jQuery的其他ajax方法几乎都是基于该方法的。
上一篇文章我们了解了Baidu ajax(当然是旧版的,还是被简化的……),那么我们想给这个简单的ajax方法添加什么功能呢?
可链式操作
既然是jQuery必然先要解决的是链式操作的问题。
jQuery中的Deferred可以实现异步链式模型实现,Promise对象可以轻易的绑定成功、失败、进行中三种状态的回调函数,然后通过在状态码在来回调不同的函数就行了。
但仅仅返回一个promise没什么用
promise只能处理异步,我们需要返回一个更有用的东西。
jqXHR就是这样的东西,实际上他是一个山寨版的XHR对象。
这样我们就可以扩展一下XHR对象的功能, 提供一定的容错处理,暴露给外部提供一些方法。
// 为了能够实现链式操作
// 顺便扩展一下xhr对象功能
// 还有提供一定的容错处理
jqXHR = {
// 准备状态
readyState: 0,
// 如果需要,创建一个响应头参数的表
getResponseHeader: function( key ) {
var match;
// 如果状态为2,状态2表示ajax完成
if ( state === 2 ) {
// 如果没有相应头
if ( !responseHeaders ) {
// 相应头设空
responseHeaders = {};
while ( (match = rheaders.exec( responseHeadersString )) ) {
// 组装相应头
responseHeaders[ match[1].toLowerCase() ] = match[ 2 ];
}
}
// 响应头对应的key的值
match = responseHeaders[ key.toLowerCase() ];
}
// 返回
return match == null ? null : match;
},
// 返回响应头字符串
getAllResponseHeaders: function() {
// 看看是否接收到了,接收到直接返回,否则为null
return state === 2 ? responseHeadersString : null;
},
// 设置请求头
setRequestHeader: function( name, value ) {
var lname = name.toLowerCase();
// 如果state不为0
if ( !state ) {
// 如果requestHeadersNames[ lname ]不为空,
// 则requestHeadersNames[ lname ]不变,name设置为该值
// 否则,requestHeadersNames[ lname ]不空,
// 则requestHeadersNames[ lname ]设置为name,
// 该映射关系用于避免用户大小写书写错误之类的问题,容错处理
name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
// 现在的name是对的,或者是第一次设置这个name,不需要容错
// 设置请求头对应值
requestHeaders[ name ] = value;
}
return this;
},
// 重写相应头content-type
overrideMimeType: function( type ) {
if ( !state ) {
s.mimeType = type;
}
return this;
},
// 对应状态的回调函数集
statusCode: function( map ) {
var code;
// 如果map存在,准备组装
if ( map ) {
// 如果状态小于2,表示旧的回调可能还没有用到
if ( state < 2 ) {
// 遍历map里面的所有code
for ( code in map ) {
// 用类似链表的方式添加,以保证旧的回调依然存在
statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
}
// 状态大于2,证明已经完成了
} else {
// 无论Deferred成功还是失败都执行当前状态回调
jqXHR.always( map[ jqXHR.status ] );
}
}
return this;
},
// 中断请求
abort: function
在很多项目中都会有在前端展现数据图表的需求,而在开发过程中,开发者往往会使用一些JavaScript库,从而更有效地达到想要的目标。最近,TechSlide上的一篇文章总结了50种用于展现图表的JavaScript库,并对每种库做了简要的说明。这对于想要选择合适JavaScript库的开发者很有参考意义。
文章作者首推的库是D3,他说到:
它非常让人惊叹,我很喜欢它的简洁性。它的文档非常完备,源代码托管在GitHub上,而且不断会添加新的示例。有一种叫做Tributary的 创建D3原型的工具,其中有很多非常棒的示例。这个库非常好,以至于xcharts、nvd3、Rickshaw、Cubism.js、dc.js、 xkcd都是基于它构建的。如果你想要做出优秀的自定义数据可视化效果,那么D3可能是你最佳选择,或者对于更简单的图,你可以选择上面所提到的基于D3 的库。最后,我强烈推荐阅读Scott Murray关于D3的免费书《Interactive Data Visualization for the Web》和《Dashing D3 tutorials》。
接下来,他列举并简要说明了其它用于展现数据、制作表格和图表的JavaScript库,列在前20位的如下:
- HighCharts——它非常强大,你可以在JSFiddle中查看和编辑大量示例。它不免费,但拥有很多客户(IBM、NASA、MasterCard等)。它还向下兼容IE 8。
- jqPlot——如果你已经在使用jQuery,不想为HighCharts付费,而且情况很简单,不需要D3那样复杂的库,那么jqPlot是很好的选择。
- dygraphs——一种开源的JavaScript库,可以做出可交互、可缩放的时间线图表。对于大数据集合非常适用。
- Protovis——和D3出自同一支团队之手,是一种免费的开源库。你可以查看这个stackoveflow 页面来了解D3与其的区别。
- Flot Charts——与jqPlot一样,Flot是一种针对jQuery的纯JavaScript库,专注于简单的用法、引人注目的外观和交互特性。
- Google Chart Tools——强大、免费、易于使用。内容丰富,从最简单的线状图到负责的层级树状图都有,在展示页面中提供了大量设计良好的图表类型。
- dc.js——基于D3的JavaScript图表库,拥有本地跨过滤器(crossfilter)的支持,并让你可以高效率地浏览大型多维数据集。
- xcharts——基于D3用于构建自定义图表的库。
- nvd3——让你可以构建可重用的图表和图表组件,同时具有d3.js的强大功能。
- rickshaw——用于创建可交互时间线图表的JavaScript工具。
- Cubism.js——用于可视化时间线的D3插件。使用了Cubism构建更好的实时仪表盘,可以从Graphite、Cube和其他源拉取数据。
- xkcd——让你可以使用D3在JavaScript中做出XKCD样式的图表。
- jQuery Sparklines——一种jQuery插件,可以直接在浏览器中创建小型的内嵌图表。
- peity——一种简单的jQuery插件,可以把元素的内容转换成简单的饼图、线图和柱状图。
- BonsaiJS——一种轻量级的图形库,拥有直观的图形API和SVG渲染器。
- Flotr——为 Prototype.js所用的JavaScript图表库。它拥有很多特性,像对负数值的支持、鼠标跟踪、选定支持、缩放支持、事件挂钩、CSS样式支 持、在画布(canvas)中包含文字、旋转的标签、渐变颜色、图形标题和子标题、电子表格、CSV数据下载等等。
- ProtoChart——物如其名,ProtoChart让你可以使用JavaScript和Prototype创建很漂亮的图表。它是一种开源库。
- Flotr2——HumbleSoftware当前正在做的项目,让你可以使用Canvas和JavaScript创建图表。
- jQuery-Visualize——HTML的table元素驱动的HTML5 canvas图表。也是针对jQuery的图表插件。
- JS Charts——基于JavaScript的图表生成器,只需要很少甚至不需要编码。免费版会有水印,可以通过付费去掉。
- ……
文章中还列举的JavaScript库有:PlotKit、MilkChart、moochart、moowheel、table2chart、Canvas 3D Graph、TufteGraph、ArborJS、TimePlot、gRaphael、ICO、Elycharts、ZingChart、RGraph、Dojo Charting、Bluff、canvasXpress、ccchart、JIT、JSXGraph、Smoothie Charts、YUI Charts、amcharts、Emprise JavaScript Charts、FusionCharts、JavaScript Diagram Builder、jGraph、Sencha Touch Charts、Style Chart、AwesomeChartJS等,都各有千秋,如果你对这些库感兴趣的话,可以访问相应的链接或者阅读原文。
这个列表对于想要利用JavaScript技术创建图表展现数据的开发者来说,非常具有参考意义,你可以从中选择最适合的库,从而高效、高质量地完成任务。
本文链接
onMouseOver 和 onMouseOut事件是移入移出事件,当鼠标移入或者移出某元素时希望能有不同的显示效果或者执行一段js函数, 比如鼠标移入一个div框中希望这个框背景色会改变,移出时又恢复原样,这是网页设计常用的效果,但当div框有子元素时,背景色会闪动,因为发生了冒泡事件。
IE下有 onmouseenter和onmouseleave来解决。
兼容方式:
function toolClose(dl,e){ var relatedTarget = e.toElement || e.relatedTarget; while(relatedTarget && relatedTarget != dl) relatedTarget = relatedTarget.parentNode; if(!relatedTarget){ dl.parentNode.className='fore3 menu'; } }
<dl onmouseover="toolOpen(this)" onmouseout="toolClose(this,event)" >