Underscore JS 中文文档

Underscore 是一个JavaScript实用库,提供了类似Prototype.js (或 Ruby)的一些功能,但是没有继承任何JavaScript内置对象。它弥补了部分jQuery没有实现的功能,同时又是Backbone.js必不可少的部分。

我主要是用来在mongo中使用其一些常用数组的操作,如果有更好的工具,请友情告之。

Underscore提供了80多个函数,包括常用的: map, select, invoke — 当然还有更多专业的辅助函数,如:函数绑定, JavaScript模板功能, 强类型相等测试, 等等. 在新的浏览器中, 有许多函数如果浏览器本身直接支持,将会采用原生的,如 forEach, map, reduce, filter, every, some 和 indexOf.

下载地址:
http://learning.github.io/underscore/underscore-min.js

集合函数 (数组或对象)

each_.each(list, iterator, [context]) 别名: forEach
对一个 list 的所有元素进行迭代, 对每一个元素执行 iterator 函数. iterator 和 context 对象绑定, 如果传了这个参数. 每次 iterator 的调用将会带有三个参数: (element, index, list). 如果 list 是一个 JavaScript 对象, iterator 的参数将会是 (value, key, list). 如果有原生的 forEach 函数就会用原生的代替.

_.each([1, 2, 3], alert);
=> 依次alert每个数字...
_.each({one: 1, two: 2, three: 3}, alert);
=> 依此alert每个数字...
注意:集合函数对于数组、对象、以及arguments,NodeList等类似数组的对象都有用。但是对鸭子类型对象也有用,所以请避免传入拥有length属性的对象。

map_.map(list, iterator, [context]) 别名: collect
映射 list 里的每一个值, 通过一个转换函数(iterator)产生一个新的数组. 如果有原生的 map 函数, 将用之代替. 如果 list 是一个 JavaScript 对象, iterator的参数将会是 (value, key, list).

_.map([1, 2, 3], function(num){ return num * 3; });
=> [3, 6, 9]
_.map({one: 1, two: 2, three: 3}, function(num, key){ return num * 3; });
=> [3, 6, 9]
reduce_.reduce(list, iterator, memo, [context]) 别名: inject, foldl
也被称为 inject 和 foldl, reduce 将一个 list 里的所有值归结到一个单独的数值. Memo 是归结的初始值, 而且每一步都由 iterator返回. 迭代器 iterator 会传入四个参数: memo, value 和迭代的索引index (或 key), 最后还有对整个 list 的一个引用.

var sum = _.reduce([1, 2, 3], function(memo, num){ return memo + num; }, 0);
=> 6
reduceRight_.reduceRight(list, iterator, memo, [context]) 别名: foldr
reduce的右结合版本. 如果可能, 将调用 JavaScript 1.8 版本原生的 reduceRight. Foldr 在 JavaScript 中并没那么有用, 人们对它的评价并不好.

var list = [[0, 1], [2, 3], [4, 5]];
var flat = _.reduceRight(list, function(a, b) { return a.concat(b); }, []);
=> [4, 5, 2, 3, 0, 1]
find_.find(list, iterator, [context]) 别名: detect
从list里进行逐项查找,返回第一个符合测试(iterator)条件的元素,如果没有的话则返回undefined。 此函数只返回第一个符合条件的元素,并不会遍历整个list。

var even = _.find([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; });
=> 2
filter_.filter(list, iterator, [context]) 别名: select
在 list 里的每一项进行查找, 返回一个符合测试 (iterator) 条件的所有元素的集合. 如果存在原生的 filter 方法, 将采用原生的.

var evens = _.filter([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; });
=> [2, 4, 6]
where_.where(list, properties)
遍历 list 里的每一个值, 返回包含 properties 里所有 key-value 组合的对象的数组.

_.where(listOfPlays, {author: "Shakespeare", year: 1611});
=> [{title: "Cymbeline", author: "Shakespeare", year: 1611},
{title: "The Tempest", author: "Shakespeare", year: 1611}]
findWhere_.findWhere(list, properties)
从list里进行逐项查找,返回第一个符合properties里键值对的元素,如果没有的话则返回undefined。

如果没有找到符合的元素,或者list为空,将会返回undefined。

_.findWhere(publicServicePulitzers, {newsroom: "The New York Times"});
=> {year: 1918, newsroom: "The New York Times",
reason: "For its public service in publishing in full so many official reports,
documents and speeches by European statesmen relating to the progress and
conduct of the war."}
reject_.reject(list, iterator, [context])
返回在 list 不能通过测试 (iterator) 的所有元素的集合. 与 filter 相反.

var odds = _.reject([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; });
=> [1, 3, 5]
every_.every(list, [iterator], [context]) 别名: all
如果所有在 list 里的元素通过了 iterator 的测试, 返回 true. 如果存在则使用原生的 every 方法.

_.every([true, 1, null, 'yes'], _.identity);
=> false
some_.some(list, [iterator], [context]) 别名: any
如果任何 list 里的任何一个元素通过了 iterator 的测试, 将返回 true. 一旦找到了符合条件的元素, 就直接中断对list的遍历. 如果存在, 将会使用原生的 some 方法.

_.some([null, 0, 'yes', false]);
=> true
contains_.contains(list, value) 别名: include
如果 value 存在与 list 里, 返回 true. 如果 list 是一个数组, 内部会使用 indexOf.

_.contains([1, 2, 3], 3);
=> true
invoke_.invoke(list, methodName, [*arguments])
在 list 里的每个元素上调用名为 methodName 的函数. 任何附加的函数传入, invoke 将会转给要调用的函数.

_.invoke([[5, 1, 7], [3, 2, 1]], 'sort');
=> [[1, 5, 7], [1, 2, 3]]
pluck_.pluck(list, propertyName)
一个 map 通常用法的简便版本: 提取一个集合里指定的属性值.

var stooges = [{name: 'moe', age: 40}, {name: 'larry', age: 50}, {name: 'curly', age: 60}];
_.pluck(stooges, 'name');
=> ["moe", "larry", "curly"]
max_.max(list, [iterator], [context])
返回 list 里最大的元素. 如果传入了 iterator, 它将用来比较每个值.

var stooges = [{name: 'moe', age: 40}, {name: 'larry', age: 50}, {name: 'curly', age: 60}];
_.max(stooges, function(stooge){ return stooge.age; });
=> {name: 'curly', age: 60};
min_.min(list, [iterator], [context])
返回 list 里最小的元素. 如果传入了 iterator, 它将用来比较每个值.

var numbers = [10, 5, 100, 2, 1000];
_.min(numbers);
=> 2
sortBy_.sortBy(list, iterator, [context])
返回一个经过排序的 list 副本, 用升序排列 iterator 返回的值. 迭代器也可以用字符串的属性来进行比较(如length).

_.sortBy([1, 2, 3, 4, 5, 6], function(num){ return Math.sin(num); });
=> [5, 4, 6, 3, 1, 2]
groupBy_.groupBy(list, iterator)
把一个集合分为多个集合, 通过 iterator 返回的结果进行分组. 如果 iterator 是一个字符串而不是函数, 那么将使用 iterator 作为各元素的属性名来对比进行分组.

_.groupBy([1.3, 2.1, 2.4], function(num){ return Math.floor(num); });
=> {1: [1.3], 2: [2.1, 2.4]}

_.groupBy(['one', 'two', 'three'], 'length');
=> {3: ["one", "two"], 5: ["three"]}
indexBy_.indexBy(list, iterator, [context])
Given a list, and an iterator function that returns a key for each element in the list (or a property name), returns an object with an index of each item. Just like groupBy, but for when you know your keys are unique.

var stooges = [{name: 'moe', age: 40}, {name: 'larry', age: 50}, {name: 'curly', age: 60}];
_.indexBy(stooges, 'age');
=> {
"40": {name: 'moe', age: 40},
"50": {name: 'larry', age: 50},
"60": {name: 'curly', age: 60}
}
countBy_.countBy(list, iterator)
把一个数组分组并返回每一组内对象个数. 与 groupBy 相似, 但不是返回一组值, 而是组内对象的个数.

_.countBy([1, 2, 3, 4, 5], function(num) {
return num % 2 == 0 ? 'even': 'odd';
});
=> {odd: 3, even: 2}
shuffle_.shuffle(list)
返回一个随机乱序的 list 副本, 使用 Fisher-Yates shuffle 来进行随机乱序.

_.shuffle([1, 2, 3, 4, 5, 6]);
=> [4, 1, 6, 3, 5, 2]
sample_.sample(list, [n])
从 list 里进行随机取样. 传一个数字 n 来决定返回的样本个数, 否则只返回一个样本.

_.sample([1, 2, 3, 4, 5, 6]);
=> 4

_.sample([1, 2, 3, 4, 5, 6], 3);
=> [1, 6, 2]
toArray_.toArray(list)
将一个 list (任何可以被进行迭代的对象)转换成一个数组. 在转换 arguments 对象时非常有用.

(function(){ return _.toArray(arguments).slice(1); })(1, 2, 3, 4);
=> [2, 3, 4]
size_.size(list)
返回 list 里所有元素的个数.

_.size({one: 1, two: 2, three: 3});
=> 3

数组函数

注意: 所有数组函数都可以用在 arguments 对象上. 然而, Underscore 函数的设计并不只是针对稀疏数组的.

first_.first(array, [n]) 别名: head, take
返回数组 array 里的第一个元素. 如果传了参数 n 将返回数组里前 n 个元素.

_.first([5, 4, 3, 2, 1]);
=> 5
initial_.initial(array, [n])
返回一个数组里除了最后一个元素以外的所有元素. 在arguments对象上特别有用. 传参 n 将排除数组最后的 n 个元素.

_.initial([5, 4, 3, 2, 1]);
=> [5, 4, 3, 2]
last_.last(array, [n])
返回数组 array 里的最后一个元素. 传参 n 将返回 数组里的后 n 个元素.

_.last([5, 4, 3, 2, 1]);
=> 1
rest_.rest(array, [index]) 别名: tail, drop
返回一个数组里除了第一个以外 剩余的 所有元素. 传参 index 将返回除了第 index 个元素以外剩余的所有元素.

_.rest([5, 4, 3, 2, 1]);
=> [4, 3, 2, 1]
compact_.compact(array)
返回一个数组 array 除空(真值检验为false)后的副本. 在JavaScript里, false, null, 0, "", undefined 和 NaN 真值检验的结果都为false.

_.compact([0, 1, false, 2, '', 3]);
=> [1, 2, 3]
flatten_.flatten(array, [shallow])
将一个嵌套多层的数组 array (嵌套可以是任何层数)转换为只有一层的数组. 如果传参 shallow 为true, 数组只转换第一层.

_.flatten([1, [2], [3, [[4]]]]);
=> [1, 2, 3, 4];

_.flatten([1, [2], [3, [[4]]]], true);
=> [1, 2, 3, [[4]]];
without_.without(array, [*values])
返回一个除去所有 values 后的 array 副本.

_.without([1, 2, 1, 0, 3, 1, 4], 0, 1);
=> [2, 3, 4]
union_.union(*arrays)
返回传入的多个数组 arrays 结合后的数组: 且所有数组元素都是唯一的, 传入的数组可以是一个或多个数组 arrays.

_.union([1, 2, 3], [101, 2, 1, 10], [2, 1]);
=> [1, 2, 3, 101, 10]
intersection_.intersection(*arrays)
返回一个多个数组 arrays 的交集. 即返回的数组里每个元素, 都存在于参数 arrays 每个数组里.

_.intersection([1, 2, 3], [101, 2, 1, 10], [2, 1]);
=> [1, 2]
difference_.difference(array, *others)
跟 without 相似, 但是返回的数组是 array 里跟别的数组 other 里不一样的元素.

_.difference([1, 2, 3, 4, 5], [5, 2, 10]);
=> [1, 3, 4]
uniq_.uniq(array, [isSorted], [iterator]) 别名: unique
返回 array 去重后的副本, 使用 === 做相等测试. 如果您确定 array 已经排序, 给 isSorted 参数传如 true, 此函数将使用更快的算法. 如果要处理对象元素, 传参 iterator 来获取要对比的属性.

_.uniq([1, 2, 1, 3, 1, 4]);
=> [1, 2, 3, 4]
zip_.zip(*arrays)
合并 arrays 里每一个数组的每个元素, 并保留对应位置. 在合并分开保存的数据时很有用. 如果你用来处理矩阵嵌套数组时, zip.apply 可以做类似的效果.

_.zip(['moe', 'larry', 'curly'], [30, 40, 50], [true, false, false]);
=> [["moe", 30, true], ["larry", 40, false], ["curly", 50, false]]

_.zip.apply(_, arrayOfRowsOfData);
=> arrayOfColumnsOfData
object_.object(list, [values])
把数组转换成对象. 传一个或多个 [key, value] 形式的数组, 或者一个包含key的数组和一个包含value的数组.

_.object(['moe', 'larry', 'curly'], [30, 40, 50]);
=> {moe: 30, larry: 40, curly: 50}

_.object([['moe', 30], ['larry', 40], ['curly', 50]]);
=> {moe: 30, larry: 40, curly: 50}
indexOf_.indexOf(array, value, [isSorted])
返回元素 value 在数组 array 里的索引位置, 如果元素没在数组 array 中, 将返回 -1. 此函数将使用原生的 indexOf 方法, 除非原生的方法无故消失或者被覆盖重写了, 才使用非原生的. 如果您要处理一个大型数组, 而且确定数组已经排序, 参数 isSorted 可以传 true, 函数将使用更快的二分搜索来进行处理... 或者, 传一个数字作为 第三个参数, 以便于在指定索引之后开始寻找对应值.

_.indexOf([1, 2, 3], 2);
=> 1
lastIndexOf_.lastIndexOf(array, value, [fromIndex])
返回元素 value 在数组 arrry 里最后一次出现的索引位置, 如果元素没在数组 array 中, 将返回 -1. 如有可能, 此函数将使用原生的 lastIndexOf 方法. 传参 fromIndex 以便从指定索引开始寻找.

_.lastIndexOf([1, 2, 3, 1, 2, 3], 2);
=> 4
sortedIndex_.sortedIndex(list, value, [iterator])
为了保持 list 已经排好的顺序, 使用二分搜索来检测 value 应该 插入到 list 里的所在位置的索引. 如果传入了一个 iterator , 它将用来计算每个值的排名, 包括所传的 value 参数.

_.sortedIndex([10, 20, 30, 40, 50], 35);
=> 3

var stooges = [{name: 'moe', age: 40}, {name: 'curly', age: 60}];
_.sortedIndex(stooges, {name: 'larry', age: 50}, 'age');
=> 1
range_.range([start], stop, [step])
一个灵活创建范围内整数数组的函数, each 和 map 循环整合的简便版本. 如果省略start 参数, 默认为 0; step 默认为 1. 返回一个数组, 包含从 start 到 stop (不包含stop) 范围内, 以 step 递增(减)的整数.

_.range(10);
=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
_.range(1, 11);
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
_.range(0, 30, 5);
=> [0, 5, 10, 15, 20, 25]
_.range(0, -10, -1);
=> [0, -1, -2, -3, -4, -5, -6, -7, -8, -9]
_.range(0);
=> []
与函数有关的函数

bind_.bind(function, object, [*arguments])
绑定函数 function 到对象 object 上, 也就是无论何时函数被调用, 函数里的 this 都指向 object. 可选参数 arguments 可以绑定到函数 function , 可以填充函数所需要的参数, 这也被成为 部分应用.

var func = function(greeting){ return greeting + ': ' + this.name };
func = _.bind(func, {name: 'moe'}, 'hi');
func();
=> 'hi: moe'
bindAll_.bindAll(object, [*methodNames])
绑定 methodNames 指定的方法到 object 上, 当这些方法被执行时将在对象的上下文执行. 绑定函数用作事件处理时非常方便, 否则函数调用时 this 关键字根本没什么用. 如果不传 methodNames 参数, 对象里的所有方法都被绑定.

var buttonView = {
label : 'underscore',
onClick: function(){ alert('clicked: ' + this.label); },
onHover: function(){ console.log('hovering: ' + this.label); }
};
_.bindAll(buttonView, 'onClick', 'onHover');
// 当按钮被点击, this.label将会取到正确的值, 即buttonView里的label而不是按钮的label.
jQuery('#underscore_button').bind('click', buttonView.onClick);
partial_.partial(function, [*arguments])
Partially apply a function by filling in any number of its arguments, without changing its dynamic this value. A close cousin of bind.

var add = function(a, b) { return a + b; };
add5 = _.partial(add, 5);
add5(10);
=> 15
memoize_.memoize(function, [hashFunction])
通过缓存计算结果使函数 function 具有记忆功能. 在优化耗时较长的算时法非常有用. 如果传了可选参数 hashFunction, 将用其返回的值作为key来保存函数的运行结果, 以原始函数的参数为基础. hashFunction 默认使用被缓存函数的第一个参数作为key.

var fibonacci = _.memoize(function(n) {
return n < 2 ? n: fibonacci(n - 1) + fibonacci(n - 2); }); delay_.delay(function, wait, [*arguments]) 和 setTimeout 方法很像, 在 wait 毫秒之后调用 function 函数. 如果传了可选参数 arguments, 在函数 function 调用的时候会作为参数传入. var log = _.bind(console.log, console); _.delay(log, 1000, 'logged later'); => 'logged later' // 一秒钟后显示.
defer_.defer(function, [*arguments])
延迟调用 function 函数, 直到当前调用栈被清空为止, 跟使用 setTimeout 赋予0毫秒的延时很像. 对执行高消耗算法或大型HTML呈现而不阻碍UI更新线程很有用. 如果传了可选参数 arguments, 在函数 function 调用的时候会作为参数传入.

_.defer(function(){ alert('deferred'); });
// 将在alert显示之前返回这个function
throttle_.throttle(function, wait)
返回一个类似于节流阀一样的函数, 当高频率的调用函数, 实际上会每隔 wait 毫秒才会调用一次. 对于高到您感觉不到的高频率执行的函数时非常有用.

By default, throttle will execute the function as soon as you call it for the first time, and, if you call it again any number of times during the wait period, as soon as that period is over. If you'd like to disable the leading-edge call, pass {leading: false}, and if you'd like to disable the execution on the trailing-edge, pass
{trailing: false}.

var throttled = _.throttle(updatePosition, 100);
$(window).scroll(throttled);
debounce_.debounce(function, wait, [immediate])
返回 function 函数的防反跳版本, 将延迟函数的执行(真正的执行)在函数最后一次调用时刻的 wait 毫秒之后. 对于必须在一些输入(多是一些用户操作)停止到达之后执行的行为有帮助。 例如: 渲染一个Markdown格式的评论预览, 当窗口停止改变大小之后重新计算布局, 等等.

传参 immediate 为 true 会让 debounce 在 wait 间隔之后 触发最后的函数调用而不是最先的函数调用. 在类似不小心点了提交按钮两下而提交了两次的情况下很有用.

var lazyLayout = _.debounce(calculateLayout, 300);
$(window).resize(lazyLayout);
once_.once(function)
创建一个只能运行一次的函数. 重复调用此修改过的函数会没有效果, 只会返回第一次执行时返回的结果. 作为初始化函数使用时非常有用, 不用再设一个boolean值来检查是否已经初始化完成.

var initialize = _.once(createApplication);
initialize();
initialize();
// Application只会创建一次.
after_.after(count, function)
创建一个函数, 只有在运行了 count 次之后才有效果. 在处理同组异步请求返回结果时, 如果你要确保同组里所有异步请求完成之后才 执行这个函数, 这将非常有用.

var renderNotes = _.after(notes.length, render);
_.each(notes, function(note) {
note.asyncSave({success: renderNotes});
});
// renderNotes 只会运行一次, 而且是在所有 notes 保存完毕之后才执行.
wrap_.wrap(function, wrapper)
将第一个函数 function 封装到函数 wrapper 里面, 并把函数 function 作为第一个参数传给 wrapper. 这样可以让 wrapper 在 function 运行之前和之后 执行代码, 调整参数然后附有条件地执行.

var hello = function(name) { return "hello: " + name; };
hello = _.wrap(hello, function(func) {
return "before, " + func("moe") + ", after";
});
hello();
=> 'before, hello: moe, after'
compose_.compose(*functions)
返回函数集 functions 组合后的复合函数, 也就是一个函数执行完之后把返回的结果再作为参数赋给下一个函数来执行. 以此类推. 在数学里, 把函数 f(), g(), 和 h() 组合起来可以得到复合函数 f(g(h())).

var greet = function(name){ return "hi: " + name; };
var exclaim = function(statement){ return statement.toUpperCase() + "!"; };
var welcome = _.compose(greet, exclaim);
welcome('moe');
=> 'hi: MOE!'

对象函数

keys_.keys(object)
获取 object 对象的所有属性名.

_.keys({one: 1, two: 2, three: 3});
=> ["one", "two", "three"]
values_.values(object)
获取 object 对象的所有属性值.

_.values({one: 1, two: 2, three: 3});
=> [1, 2, 3]
pairs_.pairs(object)
把一个对象转换成一个 [key, value] 形式的数组.

_.pairs({one: 1, two: 2, three: 3});
=> [["one", 1], ["two", 2], ["three", 3]]
invert_.invert(object)
返回一个 object 的副本, 并且里面键和值是对调的. 要使之有效, 必须确保object里所有的值都是唯一的且可以序列号成字符串.

_.invert({Moe: "Moses", Larry: "Louis", Curly: "Jerome"});
=> {Moses: "Moe", Louis: "Larry", Jerome: "Curly"};
functions_.functions(object) 别名: methods
返回一个对象里所有的方法名, 而且是已经排序的 — 也就是说, 对象里每个方法(属性值是一个函数)的名称.

_.functions(_);
=> ["all", "any", "bind", "bindAll", "clone", "compact", "compose" ...
extend_.extend(destination, *sources)
复制 source 对象的所有属性到 destination 对象上, 然后返回 destination 对象. 复制是按顺序的, 所以后面的对象属性会把前面的对象属性覆盖掉(如果有重复).

_.extend({name: 'moe'}, {age: 50});
=> {name: 'moe', age: 50}
pick_.pick(object, *keys)
返回一个 object 对象的副本, 过滤掉除了 keys 以外的所有属性(一个或多个).

_.pick({name: 'moe', age: 50, userid: 'moe1'}, 'name', 'age');
=> {name: 'moe', age: 50}
omit_.omit(object, *keys)
返回一个 object 对象的副本, 过滤掉了黑名单里的 keys (keys可以是单个key也可以是包含多个key的数组).

_.omit({name: 'moe', age: 50, userid: 'moe1'}, 'userid');
=> {name: 'moe', age: 50}
defaults_.defaults(object, *defaults)
用 defaults 对象里的默认值来填充 object 对象里遗漏的属性值, 并返回 object 对象. 当属性值已被填充遗漏, 再添加属性值就没用了.

var iceCream = {flavor: "chocolate"};
_.defaults(iceCream, {flavor: "vanilla", sprinkles: "lots"});
=> {flavor: "chocolate", sprinkles: "lots"}

前端框架推荐清单

via:http://www.cnblogs.com/skyme/archive/2012/07/26/2610084.html

在做web开发的时候难免遇到一个问题,那就是,选择什么样的框架。下面把前端的框架简单的列一下。

1、flex

Apache基金会今天发布了Flex 4.8版本,这是Adobe将Flex捐献给Apache基金会后发布的第一个版本。

需要注意的是,Flex目前还在孵化阶段,还不是Apache的正式项目,Flex 4.8也不是一个正式的Apache版本。

Apache称,该版本标志着Flex新时代的开始,Flex的未来将由社区来驱动,而不是由一个公司驱动。开发者可以通过贡献代码,来帮助改进Flex,如修复bug、增加功能等。

从Macromedia卖给Adobe,然后又捐给apache,不知道搞什么名堂。不过还好没有经过大幅重构,否则就真的是悲哀了!

2、extjs

ExtJS是一种主要用于创建前端用户界面,是一个基本与后台技术无关的前端ajax框架。

功能丰富,无人能出其右。

无论是界面之美,还是功能之强,ext的表格控件都高居榜首。

 

华丽的界面,灵活的功能,还有开发工具都是配套的,但有个最大的问题,用就得花钱!

3、easyui

easyui帮助你构建你的web应用更加容易。

它是一个基于jquery的插件,开发出来的一套轻量级的ui框架,非常小巧而且功能丰富。

官方网站是:

http://www.jeasyui.com/

但是她有一个最大的问题就是代码只能找到以前的开源的版本,到了1.2以后的版本源代码都是经过混淆的,如果遇到问题修改起来会非常麻烦!不过一个比较大的优势是开源免费,并且界面做的还说的过去!

4、MiniUI

又一个基于jquery的框架,开发的界面功能都很丰富。

jQuery MiniUI - 快速开发WebUI。

它能缩短开发时间,减少代码量,使开发者更专注于业务和服务端,轻松实现界面开发,带来绝佳的用户体验。

使用MiniUI,开发者可以快速创建Ajax无刷新、B/S快速录入数据、CRUD、Master-Detail、菜单工具栏、弹出面板、布局导航、数据验证、分页表格、树、树形表格等典型WEB应用系统界面。

界面做的挺不错,功能也挺丰富,但是有两个比较大的问题,一个是收费,一个是没有源码,说白了,不开源!基于这个开发如果想对功能做扩展就需要找他们的团队进行升级!

5、jQuery UI

jQuery UI 是一套 jQuery 的页面 UI 插件,包含很多种常用的页面空间,例如 Tabs(如本站首页右上角部分) 、拉帘效果(本站首页左上角)、对话框、拖放效果、日期选择、颜色选择、数据排序、窗体大小调整等等非常多的内容。

功能非常全面,界面也挺漂亮的,可以整体使用,也可以分开使用其中的几个模块,免费开源!

6、DWZ

DWZ富客户端框架(jQuery RIA framework), 是中国人自己开发的基于jQuery实现的Ajax RIA开源框架.

设计目标是简单实用,快速开发,降低ajax开发成本。

欢迎大家提出建议,我们将在下一版本中进一步调整和完善功能.共同推进国内整体ajax开发水平。

DWZ论坛 http://bbs.dwzjs.com

在线演示地址 http://demo.dwzjs.com

毕竟是国产的,支持一下,而且源码完全公开,可以选择一下!不过性能怎么样不敢确定!

7、GWT

Google 网页工具包——GWT 提供了一组基于Java语言的开发包,这个开发包的设计参考Java AWT包设计,类命名规则、接口设计、事件监听等都和AWT非常类似。熟悉Java AWT的开发者不需要花费多大的力气就能够快速的理解GWT开发工具包,将更多地时间投入到GWT应用的开发过程中。

你不用去了解这样那样的javascript框架,通过java你就可以写出功能丰富的界面,可以做单元测试,毕竟是google的产品,严重支持一下!

8、YUI

Yahoo! UI Library (YUI) 是一个开放源代码的 JavaScript 函数库,为了能建立一个高互动的网页,它采用了AJAX, DHTML 和 DOM 等程式码技术。它也包含了许多 CSS 资源。使用授权为 BSD许可证,基本上没怎么研究过!

YUI Compressor倒是挺出名的,这套UI库不知道应用的情况怎么样!

9、Sencha

Sencha 是由 ExtJS、jQTouch 以及 Raphael 三个项目合并而成的一个新项目。

大公司的框架,并且是几样库的强强联合,值得推荐!

10、Dojo

在国内应用好像不是很广,不过性能上应该没问题。

Dojo是一个用javascript语言实现的开源DHTML工具包。

有多个基金会的支持,包括IBM和SUN,都是软件界的泰斗,值得信赖!

11、ZK

ZK是一套以 AJAX/XUL/Java 为基础的网页应用程式开发框架,用于丰富网页应用程式的使用接口。最大的好处是,在设计AJAX网络应用程式时,轻松简便的操作就像设计桌面程式一样。 ZK包含了一个以AJAX为基础、事件驱动(event-driven)、高互动性的引擎,同时还提供了多样丰富、可重复使用的XUL与HTML组件,以 及以 XML 为基础的使用接口设计语言 ZK User-interfaces Markup Language (ZUML)。

在线的demo

设计器的demo

日历组件

功能丰富,全面,文档齐全,而且升级了很多次,非常值得推荐!

12、OperaMasks-UI

OperaMasks-UI是OperaMasks团队 2011下半年打造的一款轻量级前端JS组件库,旨在提供一款学习曲线低、定制性灵活、样式统一,且多浏览器支持、覆盖企业业务场景的前端 JavaScript UI组件库。目前,该团队已将这一产品以LGPL 开源协议开放给社区。

文档丰富,功能齐全,而且很容易使用和开发!而且是国产的哟!

13、JavaFX

Sun公司(已于2009年被Oracle公司收购)在2008年12月05日发布了JavaFX技术的正式版,它使您能利用 JavaFX 编程语言开发富互联网应用程序(RIA)。JavaFX Script 编程语言(以下称为JavaFX)是Sun微系统公司开发的一种declarative, statically typed(声明性的、静态类型)脚本语言。JavaFX技术有着良好的前景,包括可以直接调用Java API的能力。因为 JavaFX Script是静态类型,它同样具有结构化代码、重用性和封装性,如包、类、继承和单独编译和发布单元,这些特性使得使用Java技术创建和管理大型程序变为可能。