一.动态语言与闭包1.语法域和执行域 所谓语法域,是指定义某个程序段落的区域,所谓执行域,是指调用某个程序段落时所影响到的区域。 静态语言中,语法域与执行域基本是确定的,但是在动态语言中语法域与执行域基本一般不同,执行域通常比语法域大很多。2.一个体现闭包本质的例子 所谓闭包,是指语法域位于某个特定的区域,具有持续参考(读写)位于该区域内自身范围之外的执行域上的非持久型变量值的能力的段落!这些外部执行域的非持久型变量神奇地保留他们在闭包最初定义是的值。javascript闭包通常是通过定义在函数内部体function来实现的。<html> <head> </heaRead More
posted @ 2011-03-09 11:09 dushaobin Views(1052) Comments(4) Edit

What does it do?

The comma operator evaluates both of its operands (from left to right) and returns the value of the second operand. (MDC)

 

var a = (7, 5);
a; //5

var x, y, z
x = (y=1, z=4);
x; //4
y; //1
z; //4


 
Why did you wrap those variable assignments in parentheses?

 

Because of operator precedence. A JavaScript statement can contain multiple, disparate operators. The following statement has three operators (*+ and ,) :

 

return 5 * 2 + 3,  22;


 
Operator precedence determines the order in which operators are evaluated within a statement. The full list, in order of precedence is here. The comma operator has the lowest precedence of any operator. Lets simulate how this applies to the above example:

 

 

//original
return 5 * 2 + 3,  22;
//apply * operator
return 10 + 3,  22;
//apply + operator
return 13, 22;
//apply , operator
return 22;


 
Now let’s use that knowledge to see what would happen if we hadn’t wrapped the variable assignment in parentheses:

 

 

//original
var a = 7, 5;
//apply = operator
var a, 5; //a is now 7
//SyntaxError: missing variable name 


 
By wrapping the right hand expression in parentheses we create a group – which, effectively has the highest precedence. This ensures that the comma operator gets applied first:

 

 

//original
var a = (7, 5);
//apply group
var a = 5; 


 
In practice, lowest operator precedence actually makes the comma operator quite powerful. In effect it says: go ahead and see to all those other little operations first, then watch me come and clobber the result.

 

Some statements contain multiple commas. How does that work?

The above rule still applies. Each comma operator in the statement is processed in sequence from left to right.

 

var a = (1, 2, 3, 4);
a; //4


 
This is equivalent to:

 

 

var a = (((1, 2), 3), 4);
a; //4


 
What about commas used in type literals and declarations?

 

These are comma separators not comma operators. The purpose of a comma separator is to delimit members in a list. For example:

 

//set 4 array elements
var arr = [1, 2, 3, 4];

//create an object with 2 properties
var obj = {
  a: 22,
  f: function() {return this.a*this.a}
}

//define 3 distinct variables
var a = 1, b = 2, c = 3;

//invoke a function passing 2 arguments
Math.max(4, 7);


 
Why use comma operators?

 

Because they let you specify more than one expression where JavaScript expects only one. Comma operators are rarely essential but often useful and just occasionally downright elegant:

 

var r = [], n = 0, a = 0, b = 1, next;

function nextFibonacci() {
    next = a + b;
    return b = (a = b, next);
}

while(n++ < 10) {
    r.push(nextFibonacci());
}

r; //[1, 2, 3, 5, 8, 13, 21, 34, 55, 89]


 

function getRandomPrime() {
    while(n = Math.round(Math.random()*1000000000), !isPrime(n));
    return n;
}

var isPrime = function(n) {
    d = Math.ceil(Math.sqrt(n));
    while(n%(d--) && d);
    return !d;
}

getRandomPrime(); //425593109
getRandomPrime(); //268274719


 
Isn’t the comma operator just a semicolon in disguise?

 

Semicolons partition statements. Comma operators partition expressions within statements.

Why wouldn’t I just use the && operator to evaluate multiple expressions sequentially?

The comma operator is a close cousin of the && and || operators. All three operators will return the last expression they evaluate. The distinction is straightforward:

 

//(LHE: left hand expression, RHE right hand expression)

LHE && RHE
1. Always evaluate LHE
2. If LHE is true, evaluate RHE

LHE || RHE
1. Always evaluate LHE
2. If LHE is false, evaluate RHE

LHE, RHE
1. Always evaluate LHE
2. Always evaluate RHE


 
Choose the comma operator when both expressions must always be evaluated.

 

How about some more examples?

Okay. Earlier on I mentioned that comma operators let you specify more than one expression where JavaScript expects only one. This is perhaps most useful within the confines of the for loop:

for loops

Here’s an alternate version of a fibonacci generator, also using the comma operator:

 

for (
    var i=2, r=[0,1];
    i<15;
    r.push(r[i-1] + r[i-2]), i++
); 

r //"0,1,1,2,3,5,8,13,21,34,55,89,144,233,377" 


 
For another example, consider a utility that helps a store clerk select the bills and coins that make up a customer’s change. Here’s the basic version. We use a comma operator to bisect the second statement of the for loop. This lets us neatly increment our currency counter before testing against the limiting expression:

 

 

 
function toCurrency(total, values) {    
    total *= 100;     
    for(        
        var i=0,counts=[];
        counts[i]=total/values[i], total=total%values[i];
        i++
     );     
     return counts.map(Math.floor); 
} 

toCurrency(32.47, [500, 100, 25, 10, 5, 1]); //[6, 2, 1, 2, 0, 2]


 
Now here’s the same utility with added formatting for user-friendliness:

 

 

 
function toCurrency(total, values, sym) {
    total *= 100;     
    //do the calc     
    for(
        var i=0,counts=[];
        counts[i]=total/values[i], total=total%values[i];
        i++
    );     
   //format
   var results = counts.map(function(s,i) {
       return s>=1 && [Math.floor(s),"x",(sym || '$') +
            (values[i]/100).toFixed(2)].join(' ');
    });
    return results.filter(Boolean).join(', ');
}

toCurrency(19.77, [500,100,25,10,5,1]);
//"3 x $5.00, 4 x $1.00, 3 x $0.25, 2 x $0.01"
toCurrency(19.77, [500,100,50,20,10,5,1], '£');
//"3 x £5.00, 4 x £1.00, 1 x £0.50, 1 x £0.20, 1 x £0.05, 2 x £0.01"
toCurrency(19.77, [500,100,50,20,10,5,2,1], '€');
//"3 x €5.00, 4 x €1.00, 1 x €0.50, 1 x €0.20, 1 x €0.05, 1 x €0.02"


 
This following function uses the comma operator to simultaneously increment and decrement two counters within a for loop. The product of the counters is used to render a rather fetching curve in the console:

 

 

function renderCurve() {
  for(var a = 1, b = 10; a*b; a++, b--)
    console.log(new Array(a*b).join('*'));
}

renderCurve();
/*
*********
*****************
***********************
***************************
*****************************
*****************************
***************************
***********************
*****************
*********
*/


 
while loops

 

You can use a comma operator to create a succinct version of the do-while loop. This routine searches an elements ancestry looking for a tag name match. Again we use the comma to perform an action prior to checking the limiting expression:

 

function firstAncestor(el, tagName) {
  while(el = el.parentNode, el && (el.tagName != tagName.toUpperCase()));
  return el;
}

//element in http://ecma262-5.com/ELS5_HTML.htm
var a = $('Section_15.1.1.2'); 

firstAncestor(a, 'div'); //<div class="page">


 
Ternary conditionals

 

Ternary syntax allows for only one statement in each of its three components. As a general rule, if you need to use more statements you should consider using if elseinstead. However it’s sometimes more readable when the comma operator is used to combine short succinct expressions within a ternary statement:

 

//player loses
lives ? (lives--, go()) : (gameOver(), exit());


 
Debugging

 

The comma operator provides an unobtrusive way to inject console logs into your code without having to reformat (can you spot the errors that necessitated debugging in each case?)…

 

//CONTAINS AN INTENTIONAL ERROR!!!
//sum products while i > n
var i=10, n=0, total=0;
while(console.log(i,n), i-- > n++); {
    total += i*n
}

 

 

//CONTAINS AN INTENTIONAL ERROR!!!
//sum an array
var arr = [1,2,3];
for (
    var i=0, total=0;
    i<arr.length;
    console.log(i,total), total += arr[i++]);
)

 

 

//CONTAINS AN INTENTIONAL ERROR!!!
//add 4 to members of array and sum it
//(yes there are easier ways to do this!)
var testArray = [3, 5, 8, 4], total = 0;
var plusFour = testArray.map(function(e) {e + 4})
plusFour.forEach(function(n) {console.log(n), isNaN(n) || (total += n)});


 
Binding with iterators

 

@wavded posted this nifty technique for unobtrusively resetting iterators. Again, you don’t need to do it this way – but the tidiness appeals to me:

 

var colorIndex = 0, 
    colors = ["FF0000", "008000", "FF0086", "A2FF00", "0000FF", "800080"]; 

function selectNextColor(){
    return colors[colorIndex++] || colors[colorIndex = 0, colorIndex++];
}


 
Indirect calls to eval

 

eval¹ calls are normally invoked within their containing context (i.e. the this value in the evaluated code will be the same as the the this value of the surrounding code). This is problematic since there is no guarantee that repeated eval calls will originate in the same context.

As @kangax describes here, we can use the comma operator to fashion an indirect call to eval which will force it to execute in the global context²:

 

var a = {};

//attempt eval in context of object <code>a</code>
(function() {
    eval("this.alert('If you can read this I must be global!')");
}).call(a);
//TypeError: this.alert is not a function

//force eval in global context
(function() {
    (0,eval)("this.alert('If you can read this I must be global!')");
}).call(a);
//alerts: 'If you can read this I must be global!'


 
¹ discussion of the merits of eval are beyond the scope of this article ;-)
² although the ES5 standard confirms that indirect calls to eval should run in the global context, not every browser is compliant (i.e. IE <= 8).

 

Wrap Up

You could probably write perfectly good JavaScript code without ever using the comma operator. Does this mean I just wasted your time? I hope not. Just as an extensive vocabulary makes us better speakers and writers, so a comprehensive access to language features should make us better coders. The more techniques we have at our disposal the greater our ability to write elegant, succinct and readable code. Have fun with comma operators and please share your neat usage examples!

posted @ 2012-04-20 14:40 dushaobin Views(93) Comments(0) Edit

现在很多网站都用不规则矩形来罗列图片,ipad上面很多应该用也都是用的不规则的矩形,但是还要让他们各自都靠近排列,不能有空隙,

这个东西让我想起了俄罗斯方块,这个实现起来很简单,容器里面所有的块元素用绝对定位排列,如果能放的下就放在这里,如果放不下了,在队列中找到能放得下的元素放置,

实在找不到,则换行排列下一行,具体思路是这样。代码里有详细的注释直接看代码吧。

下面是一个demo:

http://steve.aliapp.com/sortRect.html,

posted @ 2012-04-16 10:37 dushaobin Views(1589) Comments(1) Edit

1.js太多要分开了,现在我要这样写了,

view->每个页面对应一个js文件,里面对应的是元素绑定,和错误正确的提示信息,主要就是与dom耦合紧密的。

logic->里面对应的是逻辑操作,比如大量的插件,与dom分离。

base->主要就是基础类库,兼容性封装,与逻辑无关。

view -> logic->base

view -> base

有问题再说!!!

posted @ 2012-03-29 12:46 dushaobin Views(85) Comments(0) Edit

源码地址:http://zhifeiji.aliapp.com/script/validate.js

 * 这个验证插件是这样的指定一个form表单
 * 里面只需要有如下的结构就可以了
 *
 * <input name="email" data-validate="vType=requried,when=blur,fail=email不正确,success=不错哦;vType=email,when=blur,fail=密码不能为空&setClass:fail,success=setClass:show;" />
 *
 * 设置说明:data-validate这个属性标明要验证的格式
 * 每个验证用分号隔开(注意英文的哦),vType表示要验证的类型,which表示那个元素触发(默认是自己), when表示什么事件会触发这个判定,fail表示验证失败会出现什么提示这里&表示and,可以有多个操作,
 * setClass表示要设置的类用:分开后跟类名,removeClass表示移除类表示你要移除哪个类,这里可以添加html代码,但是不建议添加,这样会使你的html看起来非常混乱,基本上够了
 *
 * 说明:
 * 1 class类中不能使用-,可以使用下划线(_)
 * 2 验证的表单框,禁止使用onclick=functino这样绑定事件(!importent)
 * 3 addClass removeClass 里面的样式不要相同,否则后果自负
 * 4 这里只对submit做了处理,如果是ajax提交需要自己写了哦,这里提供ajax接口
 * 5 如果验证一组,则可以通过参数传入该组信息进行分析
 * 6 如果要在框的box要改变,那就传参数吧,然后修改方法
 * 7 支持多表单,支持多信息提示,比如验证密码的复杂度,每个复杂度定义一个方法,这样就行了,这样能满足大部分情况,支持ajax验证,ajax提交信息,都需要根据具体情况添加你自己的方法了
 * 8 validFun,是写验证方法的地方,会自动分配不同方法到不同元素的事件上
 *
 *
 * addForm参数是: {id:formid,which:"self",when:"click"}
 *
 * 生成后的结构是:{id:formid,ele:form,whichEle:"self",when:""}
 *
 * 生成事件队列是很有必要的,每个元素的每个事件要有一个验证队列以便于管理
 *
 * form 数据结构不合理存在问题,需要重新设计,因为如果一个验证失败了下面的验证还会继续,下面的验证结构会覆盖上面的验证结果,不合理
 *
 * 应改为队列,每个元素的每个验证事件都要有一个事件队列如果一个失败了,就取消后面要执行的验证同时记录每个失败的验证最后统一整理
 * which,相应的改为要验证哪个元素,而不是由哪个元素来验证,否则就杯具了config,是写配置信息的地方,正则表达式都在这里
 *
 *
使用实例,自己用,写一下笔记
<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title>居中</title>
        <style type="text/css">
            .succMail {
                border: green 1px solid;
            }
            
            .failMail {
                border: red 1px solid;
            }
            
            .succNum {
                border: green 1px solid;
                background: #cccccc;
            }
            
            .failNum {
                border: green 1px solid;
                background: #eeeeee;
            }
            
            .onSucc {
                border: 1px solid #a5c760;
                background: #f4ffd4;
            }
            
            .onFail {
                border: 1px solid red;
                background: #FFDBDB;
            }
        </style>
        <script type="text/javascript" src="validatePrject/validate.js">
        </script>
		
    </head>
    <body>
        <form id="form1">
            <p>
                6-8位数字:<input id="s1" name="number" style="displayasdf;" class="asdf" data-validate="vType=required,when=blur,fail=不能为空哦!&addClass:onFail&removeClass:onSucc,success=你已经输入值了!&addClass:onFail&removeClass:onSucc;vType=number,when=blur, fail= <span>一定要输入数字哦!</span>&addClass:onFail&removeClass:onSucc,success  = 你输入的是正确的!&addClass:onSucc&removeClass:onFail ;vType=len(<8&>6),when=blur,fail=长度太长了哦!&addClass:onFail&removeClass:onSucc,success=长度很合适呵呵!&addClass:onSucc&removeClass:onFail ;" />
            </p>
            <p>
                email:<input id="s2" name="email" style="displayasdf;" class="asdf" data-validate="vType=required,when=blur,fail=邮箱不能为空!,success=正确哦!;vType=email,when=blur, fail= <span>email不正确哦!</span>& addClass : failMail &  removeClass :  succMail,success  =email输入正确哦!&addClass:succMail&removeClass:failMail;" />
            </p>
            <p>
                <input id="s3" name="userName" style="displayasdf;" class="asdf" data-validate="vType=required,when=blur,fail=username 错误& removeClass: right &addClass : worgnt,success=username正确;vType=email,when=blur, fail= <idv>密码不能为空</st>& addClass : rigte &  removeClass :  worgn &    addClass: soms,success  =duahobin&addClass:set;" />
            </p>
            <p>
                选择框:
                <select name="sx" data-validate="vType=required,when=change,fail=性别必须要选择& removeClass: right &addClass : worgnt,success=干的好!;">
                    <option></option>
                    <option value="m">男</option>
                    <option value="w">女</option>
                </select>
            </p>
            <p>
                多选:<input type="checkbox" /><span>读书</span>
                <input type="checkbox" /><span>看书</span>
                <!-- 如果是组的话就只能过滤了用参数传进来所有组成员 -->
            </p>
            <p>
                qq号:<input id="qq" name="qq" style="displayasdf;" class="asdf" data-validate="vType=required,when=blur,fail=username 错误& removeClass: right &addClass : worgnt,success=username正确;vType=email,when=blur, fail= <idv>密码不能为空</st>& addClass : rigte &  removeClass :  worgn &    addClass: soms,success  =duahobin&addClass:set;" />
            </p><input type="submit" value="提交"/>
        </form><input id="testVd" type="button" name="vem" value="验证" />
        <form id="form2">
            <p>
                6-8位数字:<input id="s1" name="number" style="displayasdf;" class="asdf" data-validate="vType=required,when=blur,fail=不能为空哦!&addClass:onFail&removeClass:onSucc,success=你已经输入值了!&addClass:onFail&removeClass:onSucc;vType=number,when=blur, fail= <span>一定要输入数字哦!</span>&addClass:onFail&removeClass:onSucc,success  = 你输入的是正确的!&addClass:onSucc&removeClass:onFail ;vType=len(<8&>6),when=blur,fail=长度太长了哦!&addClass:onFail&removeClass:onSucc,success=长度很合适呵呵!&addClass:onSucc&removeClass:onFail ;" />
            </p>
            <p>
                email:<input id="s2" name="email" style="displayasdf;" class="asdf" data-validate="vType=required,when=blur,fail=邮箱不能为空!,success=正确哦!;vType=email,when=blur, fail= <span>email不正确哦!</span>& addClass : failMail &  removeClass :  succMail,success  =email输入正确哦!&addClass:succMail&removeClass:failMail;" />
            </p>
            <p>
                <input id="s3" name="userName" style="displayasdf;" class="asdf" data-validate="vType=required,when=blur,fail=username 错误& removeClass: right &addClass : worgnt,success=username正确;vType=email,when=blur, fail= <idv>密码不能为空</st>& addClass : rigte &  removeClass :  worgn &    addClass: soms,success  =duahobin&addClass:set;" />
            </p>
            <p>
                选择框:
                <select name="sx" data-validate="vType=required,when=change,fail=性别必须要选择& removeClass: right &addClass : worgnt,success=干的好!;">
                    <option></option>
                    <option value="m">男</option>
                    <option value="w">女</option>
                </select>
            </p>
            <p>
                多选:<input type="checkbox" /><span>读书</span>
                <input type="checkbox" /><span>看书</span>
                <!-- 如果是组的话就只能过滤了用参数传进来所有组成员 -->
            </p>
            <p>
                qq号:<input id="qq" name="qq" style="displayasdf;" class="asdf" data-validate="vType=required,when=blur,fail=username 错误& removeClass: right &addClass : worgnt,success=username正确;vType=email,when=blur, fail= <idv>密码不能为空</st>& addClass : rigte &  removeClass :  worgn &    addClass: soms,success  =duahobin&addClass:set;" />
            </p><input type="submit" value="提交"/>
        </form>
        <script type="text/javascript">
            
            validator.addForm({
                id: "form1",
                which: "form1",
                when: "submit"
            });
			  
            validator.addForm({
                id: "form2",
                which: "form2",
                when: "submit"
            });
			
			
        </script>
    </body>
</html>

  

posted @ 2012-03-14 15:40 dushaobin Views(119) Comments(0) Edit

这段时间没事干就写个小日历连续,有很多东西碰到。

1.支持css3支持良好的浏览器,ie9 还凑合,ie8就杯具

2.每个js文件尽量独立,不影响其他的js文件还可以异步加载

3.不同浏览器器要有不同的版本的js,ie8 就加载ie8的js,标准就加载标准的js,好处兼容少,性能好,但是会有一些重复代码,个人认为比较好,比yui那种不管什么都加载来要好

4.还有很多要注意的地方没有优化,时间仓促,有兴趣自己搞吧,

地址:zhifeiji.aliapp.com

来两张效果图:

posted @ 2012-03-05 19:05 dushaobin Views(249) Comments(0) Edit
这个问题我的理解是只要让其他网站能执行我的脚本我就有可能危害到,这个网站的用户安全。一般的攻击就是写一段脚本看是否能执行,就能判断是否是攻击了,比如说我写<script> alert("执行了我了哦!!!"); </script>,然后看看当页面加载的时候是否能执行,就行了。目前为止一般的网站这段代码都不会执行,但是换一种方式呢?比如<SCRIPT>alert(String.fromCharCode(88,83,83))</SCRIPT>,估计也米有几个网站执行吧,大家都知道的。下面看更猥琐的测试例子, '';Read More
posted @ 2011-12-22 17:33 dushaobin Views(453) Comments(3) Edit
看到某些工具上有水波效果,想能不能用canvas实现呢,于是就google了一下还真有在这里与大家分享吧!这里有一篇教程,介绍实现原理的,水波纹原理下面是js实现的源代码var ripple = (function(img_src, container){ var img = new Image, img_data, delay = 30, width, height, half_width, half_height, riprad = 5, oldind, newind, mapind, size, ripplemap = [], last_map = [], ripple, ripp...Read More
posted @ 2011-12-21 18:25 dushaobin Views(274) Comments(2) Edit
译者注:一篇很好的文章,很久以前在blog上就推荐过,这两天断断续续花了点时间翻译了一下,推荐读读。英文原文在此。文中所有的 layout 这个单词都未作翻译,一来本身这个单词意思就比较多,翻成啥都觉得别扭,二来它也是专有的属性,所以就意会一下吧。水平有限,很多地方都是模模糊糊地意译,发现错误欢迎留言指出。引用一段来自Dean Edwards的评价:I recommend that every CSS designer and DOM scripter read this. Understanding “layout” gives a huge insight into lots of othRead More
posted @ 2011-12-09 14:33 dushaobin Views(227) Comments(1) Edit
ie6 下用javascript伪协议 有bug,首先location.href 会被改成javascript:void(0);,这种情况下,如果在用ajax方法只写相对路径的话就会有问题了,还有就是用javascript时,另外发起请求就会出问题,ie6下 a如果有新请求还是尽量避免使用javascript:协议,测试ieTester 不知道真实情况是什么!Read More
posted @ 2011-11-08 19:23 dushaobin Views(45) Comments(0) Edit
今天写代码,把click事件绑定到了document上面,当我点击鼠标右键的时候,没想到firefox出发了click事件,在ie8 chrome13 上面测试都没有触发click事件,只有firefox触发了,再次测试把click放到一个div元素上click点击鼠标右键没有触发,靠,下次注意了,不知道这是什么意思,测试代码如下<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><htRead More
posted @ 2011-11-03 11:44 dushaobin Views(972) Comments(2) Edit