感谢 popeye 的投稿。
popBaseball–拖放插件.
Demo: http://dl.getdropbox.com/u/335315/popeye/popBaseball/index.html
Down: http://dl.getdropbox.com/u/335315/popeye/popBaseball.rar
调用:
$.baseball({
accepter:"#left,#center,#right",
target:".baseball",
handle:".basebat"
})
参数说明:
accepter 容器的集合,(垒)
target 希望能拖动的元素块,也就是#left(#center||#right)的子元素
handle 元素块拖动的鼠标入口,此参数不存在时默认为target
目前功能很简单,
拖动时支持鼠标滚轮,
未支持垒的混排,因为不想在鼠标移入后才响应,
demo中有个平面分割的算法,希望有缘人可以解答。
感谢 jay.li 的投稿。
原文:http://uedmagazine.com/ued/comments.php?y=09&m=08&entry=entry090822-161544
走到今天,中国雅虎终于结束了其艰辛、曲折、多舛、充满变化的命运,结束,不一定是坏事,至少能够让人更清晰更理智的对待过去。作为我的第一份工作,在雅虎的这段经历确实带给我很多很深的思考、和一些终身受用的知识和道理,只是这种变化来的剧烈,亦忧亦喜的影响着身在其中的每一个人,前两天还在抱怨蒋大仙人作的“YAHOO Engineer@CN”的T恤的各种瑕疵,突然就成了绝版,怎能不让人心生感慨。不管是遗憾、还是无奈,不论是终结、还是重生、这种缺憾美,仍然深深的感染着那些曾经真正在乎过yahoo的每一个人。

我第一次接触雅虎是在大学一年级的时候,那时第一次去学校机房就作了两件事,申请了一个163的信箱,在雅虎注册了一个帐号,接下来的一段时间里常泡在雅虎聊天室中,直到有了自己的QQ号。当时的雅虎聊天室和现在雅虎通上的聊天室很类似,简单易用,当时163的聊天室人很少,碧海银沙人多热闹但很难用,甚至每次都要用鼠标去点击“发送“才能发言……之后雅虎在功能设计上一直秉承这种实用易用的风格,在界面设计上更是讲究风格简洁内容充实,最经典的就是06年版(也就是雅虎首页改版的上一版),随后网易开始模仿这种淡雅的设计一直沿用至今……
因此在设计上,雅虎保持这种充实简洁实用易用的理念,步步为营的加深着每个人对yahoo形象的印象。从技术的角度讲,雅虎是一个技术主导的公司,它的每个产品背后都有着多层次的技术沉淀,经典的雅虎技术栈是这种沉淀的一种形象概括,成为在每次新员工培训必讲的内容。另外,由于团队庞大,技术也比较复杂和多元,从上层的php到底层的c,从前端的html到后端的yapache,都体现出多元化的工程师给雅虎技术注入的新元素。最重要的,成熟的技术和充实的积累使得设计师将更多的精力放在纯粹艺术的设计上,而不必太过担心实现的难度以及性能问题。因此,产品设计和技术实现之间的良性互动使得雅虎产品创意十足的同时又能保证质量上乘。很遗憾的是,这个良好的传统在中国雅虎则没有坚持下来,原因很复杂,也没必要去追究的太细,权当一种缺憾吧。
因此,技术的积累永远不是坏事,此外,勤劳的雅虎工程师在作研发的同时也在时刻整理文档,我所见到的yahoo twiki,从入门到提高,从底端到高端,从理论到技巧、从开源社区到开发者论坛,都是内容丰富全面的,全球雅虎任何子公司的技术资料都为我共享,在yahoo twiki这个知识仓库中永远不会让人觉得枯燥乏味,也只有最朴实的工程师才能如此兢兢业业的做到事无巨细的记录和备份,如此踏实谦虚的营造一种良好的学习氛围,并深深的让人陶醉其中。
但知识的积累要转化成高质量的产品则需要组织和工程。在雅虎,多元的技术不代表没有标准和规范,反之,标准和规范无时无刻不在,影响着雅虎的产品甚至成为行业标准,css mojo、sns的iframe框架规范、yahoo商标规范等等,从ui标准到DPL,从接口的统一设计到性能的测试标准、从产品设计到实现,详尽的标准和复杂的规范使得产品可控性强,同时使得团队开发中的进度统一,协作高效。说到yahoo的商标规范,竟然落里罗嗦的有一百多页,我都ft了。作为一个全球统一的技术体系,雅虎的软件管理则延承了linux的包管理方式,yinst包管理做到了全球共享统一管理,包括雅虎关系在内的所有产品的发布都依赖于这个庞杂的包管理系统,产品升级仅仅相当于软件版本升级,如此,产品的部署将更加灵活,再复杂的产品的安装只像装包一样简单。在关系的前端开发中,为了简化操作流程我作了一个yimg的管理工具,专门应用于关系的前端开发,工具作好后不用拷贝到每个机器上再安装,只要在开发机上用install命令就可以自动安装最新版本。这种方便的包管理是很值得学习和仿效的。
所以,与其说是雅虎技术影响着每一代人,不如说这种开源共享开放的文化感染着每一代人,之前从雅虎走出去的很多牛人,对此也都深有体会。只是中国雅虎不成功的产品带给人很多遗憾,“每个人都从雅虎满载而归,却似不曾为他真正奉献过什么“,权当这是对自己的一种小小谴责吧。然而雅虎那由内而外处处散发着脱俗的实用主义的美感,留给人很多难忘的回忆。
仅已上文,祭奠我在雅虎的每个日日夜夜。但愿这是一个美好的开始,而不是无奈结束。
作者:66
Hi,大家好,我是CssRain的站长。爱好前端开发的我先后从事过Java开发,JavaScript,CSS开发等,已经工作两年+了。目前就职于亚信中国(Asiainfo),担任前端开发和创新工作。忠心希望所有的读者在这里都能够有收获和进步,同时也希望大家多多支持CssRain。这是我的最大心愿。Best Regards。
牛刀小试(2)——使用Goolge gears制作离线应用.
上篇介绍了google gears 在本地的一些应用,这篇文章将介绍如何将 我们正在浏览的网页 利用 gears 下载到本地,然后当 服务器 停止时, 本地依然能够访问。
本例需要的文件:
- tutorial_manifest.json(一个json文件,里面存了一个json对象,对象是一个你要下载到本地的文件列表)
比如:
{
"betaManifestVersion": 1,
"version": "v1",
"entries": [
{ "url": "go_offline.html"},
{ "url": "go_offline.js"},
{ "url": "../gears_init.js"},
{ "url": "../css/style.css"},
{ "url": "../images/a.gif"},
{ "url": "../images/b.gif"}
]
}
- gears_init.js (gears官方提供的初始化库 )
1.初始化gears
首先,你先引入 Google Gears 提供的 gears_init.js 來作一些基本的 Google Gears 初始化,然后,在你自己的 JavaScript 里面,加入如下代码:
function init() {
if (!window.google || !google.gears) {
textOut("注意,你必须先安装google gears!");
} else {
textOut("很好,google gears已经安装。");
}
}
2.同步到本地
这里就会使用到刚才那个json 对象了 ,通过json对象的列表文件,然后把它们下载到本地。
// 先建立 local server,这里 create 的参数不用修改。
try {
var localServer = google.gears.factory.create('beta.localserver');
} catch (ex) {
alert(ex.message);
return;
}
// 建立存储空间,名称可以自己取
var store = localServer.createManagedStore("foo-store");
// 指定 json 的 url
store.manifestUrl = MANIFEST_FILENAME;
// 开始确定版本并同步
store.checkForUpdate();
// 为了确认是否同步结束,可以加入下面的timer来检查 :
var timer = google.gears.factory.create('beta.timer');
// 每 500m 检查 一下
var timerId = timer.setInterval(function() {
// 同步完成
if (store.currentVersion) {
timer.clearInterval(timerId);
alert('同步完成');
}
}, 500);
3.例子下载
我按照官方教程 做了一个 简单 的离线浏览的例子。
你可以挂在自己本地的服务器上,先运行一次。然后把服务器停掉,然后再次用 服务器的地址 去访问。
http://www.cssrain.cn/demo/gearstutorial/gearstutorial.rar
PS:本来想在我的网站上 应用一下,结果我服务器不支持 .json 后缀的文件。 所以无法演示,但在本地localhost上 已经 测试成功。能离线使用。
作者:66
Hi,大家好,我是CssRain的站长。爱好前端开发的我先后从事过Java开发,JavaScript,CSS开发等,已经工作两年+了。目前就职于亚信中国(Asiainfo),担任前端开发和创新工作。忠心希望所有的读者在这里都能够有收获和进步,同时也希望大家多多支持CssRain。这是我的最大心愿。Best Regards。
牛刀小试——Goolge gears.
前段时间发现QQ空间也用了Google gears,所以自己也打算抽空研究一下它。我对Google gears的理解:
它是一个浏览器的插件,通过这个插件能让网站数据同步到 自己本地上 (html,css,js,images等)。所以当网站没有网络连接时,可以访问本地的数据。
下面是我做的一个在线的计划列表:
http://www.cssrain.cn/todo/index.html
这个就是必须先安装google gears ,之后允许就可以用了。
目前主要是对google gears的一些简单的操作。没有真正实现那种服务器数据跟本地数据进行同步,而是直接在本地上创建数据,删除数据,修改数据。
怎么样去同步数据,同步哪些数据可能是交互的重点。
如果有兴趣的话,可以下载源码:
http://www.cssrain.cn/todo/MyTodoList.rar
作者:不羁虫
从事IT3年左右,专业前端工作2年左右,熟悉前端体验,Web标准(大侠很多,不敢自言精通),对jQuery的认识不到一年,jq很符合前端开发的习惯,努力学习中,也正是因为jquery认识了cssrain,这里的文章和插件都很不错,非常骄傲国内能有这样熬的交流的地方。
个人开发习惯:Firefox+Firebug+Fireworks+Editplus
博客:http://hi.baidu.com/bujichong(当记事本和收藏夹用,可观性不强…)
邮箱:bujichong@163.com
qq:347408820(欢迎同行加我交流)
使用jQuery打造低成本炫彩相册.
由于需要类似EOGallery切换图片的相册效果,
但我需要的是小图处在两边居中位置固定的效果,
他的改动起来很麻烦,样式也不好控制,
想想用animate实现起来应该不难,就干脆自己来写一个,
慢慢改来还有一些需要完善,
不过基本实现了本来预期的效果
一,用绝对定位和animate实现基本相册框架
先是用了绝对定位将大图定位在中心位置,小图固定在左右都为0的位置上,
点击按钮,用animate来实现切换大小图位置。
主要代码例如:
li.eq(y).animate({top:"0",left:"150px",width:"500px",height:"333px"});
img.eq(y).animate({width:"500px",height:"333px"});
实现出来效果预览如:
http://cssrain.cn/demo/scrollGallery/index.html
当然这样还是不够的,至少大图应该是不能变形的。
二,实现大图自适应
那么第二步我们要做的就是实现大图的宽高随区域自适应,
并将大图定位在适应后的位置上,
就是要给大图一个maxHeight和一个maxWidth,
并且能够保持比例不变,
这里的主要宽高控制代码例如:
/*自动宽函数及大图动效*/
function bigImgAnimate(x) {
w=imgSize.eq(x).width();
h=imgSize.eq(x).height();
if(w>500){w=500;h=500*h/w;m=0}else{m=(500-w)/2}
li.eq(x).animate({top:"0",left:(150+m)+"px",width:w,height:h});
img.eq(x).animate({width:w,height:h});
}
大图自动宽高及位置自动,小图大小固定:
http://cssrain.cn/demo/scrollGallery/index2.html
这样基本达到了效果要求,
不够完美的主要是小图宽高还不能自适应,
作为缩微图来说,这个重要性已经不太高了。
三,小图宽高自适应及自动播放
最后我们在效果上来尽量完美他,
让小图宽高和位置也都自适应,当然在点击的一瞬间是比较耗资源的,
美化一下,将左右控制按钮放下来,小图上添加点击效果,
最后再加个自动播放,大图添加一个lightbox效果
实现出的效果如:
http://cssrain.cn/demo/scrollGallery/index3.html
代码我就不举例了,
感兴趣的话,下载下来自己看看,
呵呵,希望能提出改进的意见
此效果关键点:绝对定位 + animate 方法。
仍需或可以改进添加的地方
1,第三步实现是比较耗资源的,animate动作比较频繁
2,图片最好先预载一下,保证脚本初始的运行
3,当然图片相册可能还需要有图片说明或标题,当然这个实现起来并不难
作者:karry
Hi,大家好,我是Karry,playGoogle(玩转谷歌)的博主。07年从武汉毕业后到上海工作,先后从事过.Net开发、前端开发。现在在巨人网络(GA)任JavaScript工程师一职。专注于JavaScript编写和用户体验改善。相信细节决定成败,欢迎志同道合的朋友一起交流。
msn: karry[at]live.cn。
blog: http://www.playgoogle.com
JavaScript中的memoization(memoizing) 技术介绍.
最近在读《JavaScript 设计模式》一书,其中工厂模式中提到了memoizing技术,今天仔细整理了一下memoization 相关的资料,与大家共享。
memoization 一词是Donald Michie 根据拉丁语memorandum杜撰的一个词。相应的动词、过去分词、ing形式有memoiz、memoized、memoizing.
Memoization 是一种将函数返回值缓存起来的方法,Memoization 原理非常简单,就是把函数的每次执行结果都放入一个键值对(数组也可以,视情况而定)中,在接下来的执行中,在键值对中查找是否已经有相应执行过的值,如果有,直接返回该值,没有才 真正执行函数体的求值部分。很明显,找值,尤其是在键值对中找值,比执行函数快多了。现代 JavaScript 的开发也已经大量使用这种技术。
我们知道,在不同的浏览器中,xmlHttpRequest对象的具体实现都不同。需要判断何种浏览器以执行具体的方法。这里就有一个使用memoization来实现的例子。
- function createXHRObject = function(){
- //先把三个匿名函数缓存起来。
- var methods = [
- function(){return new XMLHttpRequest();},
- function(){return new ActiveXObject("Msxml2.XMLHTTP");},
- function(){return new ActiveXObject("Microsoft.XMLHTTP");}
- ];
- for(var i=0,len=methods.length;i<len;i++){
- try{//这里用try catch来代替了条件判断,通常我不赞成这种写法
- methods[i]();
- }
- catch(e){
- continue;//如果报异常,则执行下一次循环
- }
- // 把createXHRObject 与能正常执行的匿名函数对应起来,再调用createXHRObject不用再检测浏览器了
- createXHRObject = method[i];
- return method[i];
- }
- }
以上是一个简单的例子,第一次执行createXHRObject()的时候,会循环判断methods 中的方法,获取一个能正确执行的,并将createXHRObject的引用指向这个方法。以后再使用这个方法的时候,不用去判断,直接自动获取正确的方法。这省去了频繁的ajax调用中浏览器的检测。
当然,这个方法看上去效率的提升不是特别明显,我之所以写上来,是因为能比较清晰的理解memoization是如何实现的。在递归调用的时候,memoization的威力才能更好的显现。
一个递归的例子:
- function fib(n) {
- if (n < 2) {
- return n;
- }
- return fib(n - 1) + fib(n - 2);
- }
这是一个经典的斐波纳契序列,fib(20) 会把fib这个方法执行21891次,如果是fib(40),这会执行331160281次。
再看看如何使用memoization来实现,
- var iterMemoFib = (function() {
- var cache = [1, 1];
- var fib = function(n) {
- if (n >= cache.length) {
- //将一个递归转换成了一个
- for (var i = cache.length; i <= n; i++) {
- cache[i] = cache[i - 2] + cache[i - 1];
- }
- }
- return cache[n-1];
- }
- return fib;
- })();
将Function的原型扩展memoize 和unmemoize 方法,这样你可以对任何函数实现memoize和解除memoize,当然,这个方法要慎,对一些不是频繁执行的函数,没必要缓存:
- Function.prototype.memoize = function() {
- var pad = {};
- var self = this;
- var obj = arguments.length > 0 ? arguments[i] : null;
-
- var memoizedFn = function() {
- // 把参数作为数组保存,作为键,把函数执行的结果作为值缓存起来
- var args = [];
- for (var i = 0; i < arguments.length; i++) {
- args[i] = arguments[i];
- }
- if (!(args in pad)) {
- pad[args] = self.apply(obj, arguments);
- }
- return pad[args];
- }
- memoizedFn.unmemoize = function() {
- return self;
- }
- return memoizedFn;
- }
- Function.prototype.unmemoize = function() {
- alert("Attempt to unmemoize an unmemoized function.");
- return null;
- }
-
使用方法:
fib.memoize();
参考文档:
- Memoizing functions in JavaScript
- JavaScript Memoization
- 提升JS性能:将递归转换为迭代
- MemoizationFrom Wikipedia, the free encyclopedia
作者:karry
Hi,大家好,我是Karry,playGoogle(玩转谷歌)的博主。07年从武汉毕业后到上海工作,先后从事过.Net开发、前端开发。现在在巨人网络(GA)任JavaScript工程师一职。专注于JavaScript编写和用户体验改善。相信细节决定成败,欢迎志同道合的朋友一起交流。
msn: karry[at]live.cn。
blog: http://www.playgoogle.com
JavaScript链式调用的设计
用过jQuery的朋友一定对jQuery中方法的链式调用印象深刻,最近发布的YUI3也支持了方法的链式调用。这是一个非常不错的语法特性,能让代码更加简洁、易读。很多时候链式调用可以避免多次重复使用一个对象变量,从而减少代码,而js是一种客户端执行的脚本语言,减少代码就减少了js文件的大小,减少了服务器的压力。链式调用这么多优点,它是如何实现的呢?这篇文章就是想探讨一下这个问题。
链式调用例子如:$("p").append("test").fadeIn("fast");
看一段jQuery的源码:
append: function() {
return this.domManip(arguments, true, function(elem){
if (this.nodeType == 1)
this.appendChild( elem );
});
}
以上是jQuery中append方法的实现。append方法是向每个匹配的元素内部追加内容的方法,很明显,属于赋值操作,但是却有返回值,返回的是当前操作的dom(通常返回this指针)。这是链式调用的关键,你会发现这不过是个语法小技巧而已。
很明显,在赋值器方法中(或者本身没有返回值的方法中)很容易实现链式调用,而取值器相对来说不好实现链式调用,因为你需要取值器返回你需要的数据而不是this指针(当然,如果你坚持要实现链式方法,也可以用回调函数来实现)。
设计一个简单的支持链式调用的类:
function Dog(name,color){
this.name=name||"";
this.color=color||"";
}
Dog.prototype.setName=function(name){
this.name=name;
return this;
};
Dog.prototype.setColor(color){
this.color=color;
return this;
};
Dog.prototype.yelp(){
alert("我的名字叫:"+this.name+",我的颜色是:"+this.color);
return this;
};
使用方式:
var dog = new Dog();
dog.setName("旺财").setColor("白色").yelp();
取值器你也想支持链式调用?
那就用回调函数来实现,将本来应该返回的值直接传给回调函数,而return仍然返回this指针。接着上面的Dog类写一个方法:
Dog.prototype.getName(callback){
callback.call(this,this.name);
return this;
}
使用方式:
function showName(name){
alert(name);
}
dog.setName("旺财").getName(showName).setColor("白色");