众所周知,淘宝首页在近期做了一次较大的更新。淘宝UED的各位大神们,很有意思的在首页代码中放入了一个小彩蛋,引起网友惊呼“前端工程师在HTML中竟然撸出一个妹纸来”,上jb:
是不是很有意思呢?关于,这个妹纸的身份呢?算了,愚安还是告诉大家吧!她是淘宝视觉顾问@amei_shin,大家不要告诉她是愚安在这里八卦的哦!
当然,愚安把这个贴出来,首先是让大家了解到写代码有时候,还算是比较开心的事情,又或是自己可以找点方法让写代码变得有趣起来;然后就是想更大家分析下,这段代码是什么意思,有什么执行效果,怎么样才能写出这样的js彩蛋。
我们知道js里的Function("","")返回一个匿名函数;所以,
javascript:Function('a,l,i,t,b,u,e,d',"a=['"+[ ' :h8G895r,', ' ,hA@@@@@@@@#&5:', ' S#@Hs:;h&@@@@@@#3', ' 8@@8 r&@@@@@@A;', ' 9@@M;:r1r :9#@@@@@M;', ' h@@@&ii391, ;8GH@@@@B.', ' :#@@@8 ;5r:. iA@@@5', ' .8@@@@G ;s,: .A@@#5', ' rB@@@@Bs, .::. .;, ;@@@M ,:', ' .XM@@@@#&; sh;,..,. h@@@B sr', ' .X@@@@@H@As, ;9@@s8# si', ' sHM@@@@@@@@BXSsi::r19&@@@G 5,s1.', ' rM#@@@@@@@@@B#@#&35s38#@@@8 i3;,', ' r&M@@@@@@@@@S:sS3r ,hS@@@@@&,,i:;;.', ' ,FGP@.@e@g@g@& :;:SGM@@@@@&.:,:8&hir:', ' ;&@F@P@.@e@gBg 1HM@@@@@@Ms:,;r5h;H@,', ' G(@"@%@c@j@o: rsi&@@@@@@&: ,:,X9,.', ' riMn@ @u@s@%@c#srh G@@@@@@@B3;:,.:s::;', ' :i&d@u@.@m@j@@@t@a@oAbXaBo@.@c@o@mB"1)i;,:;;', ' sGi.;3#@@@@@@@@@@@@@@@@@@@@@@@@@@@@#9rr;,,,i,', ' h1: ,S#@@@@@@@@@@@@@@@@@@@@@@@@@@@@Xhi. ,r', ' 13i,. :X@@@@@@@@@@@@@@@@@@@@@@@@@@MXh...,;r:', ' iXh;,.. 9@@@@@@@@@@@@@@@@@@@@@@@@@@MA9hr;:is:', ' ,X9r:,,.. 3@@@@@@@@@@@@@@@@@@@@@@@@@@@@G5s;;sh,', ' 9&5i;:,,. S@@@@@@@@@@@@@@@@@@@@@@@@@@@B9hsrsh1', ' sBG93&73&53&33&13&92&72&52&32&12&91&71&51&31&11', ' &9&7&5&3&1:81,71&51&31&11&9&7&5&3&1:71,11&9&7&5&', ' 3&1:61,31&11&9&7&5&3&1:51,31&11&9&7&5&3&1:41@631' ].join("','")+"'];l=a.join(i='').replace(/\s+/g,i)[d='split'](i).reverse().join(i);l=l.substr(l.indexOf('@')+1,parseInt(l))[d](/[,:]/);while(t=l[b='shift']()){u=l[b]()[d]('&');while(e=u[b]())i+=a[t].replace(/^\s+/g,'').charAt(+e);}eval(i);")();
其实就是定义了如下的匿名函数:
function anonymous(a,l,i,t,b,u,e,d /**/) { a=[' :h8G895r,',' ,hA@@@@@@@@#&5:',' S#@Hs:;h&@@@@@@#3',' 8@@8 r&@@@@@@A;',' 9@@M;:r1r :9#@@@@@M;',' h@@@&ii391, ;8GH@@@@B.',' :#@@@8 ;5r:. iA@@@5',' .8@@@@G ;s,: .A@@#5',' rB@@@@Bs, .::. .;, ;@@@M ,:',' .XM@@@@#&; sh;,..,. h@@@B sr',' .X@@@@@H@As, ;9@@s8# si',' sHM@@@@@@@@BXSsi::r19&@@@G 5,s1.',' rM#@@@@@@@@@B#@#&35s38#@@@8 i3;,',' r&M@@@@@@@@@S:sS3r ,hS@@@@@&,,i:;;.',' ,FGP@.@e@g@g@& :;:SGM@@@@@&.:,:8&hir:',' ;&@F@P@.@e@gBg 1HM@@@@@@Ms:,;r5h;H@,',' G(@"@%@c@j@o: rsi&@@@@@@&: ,:,X9,.',' riMn@ @u@s@%@c#srh G@@@@@@@B3;:,.:s::;',' :i&d@u@.@m@j@@@t@a@oAbXaBo@.@c@o@mB"1)i;,:;;',' sGi.;3#@@@@@@@@@@@@@@@@@@@@@@@@@@@@#9rr;,,,i,',' h1: ,S#@@@@@@@@@@@@@@@@@@@@@@@@@@@@Xhi. ,r',' 13i,. :X@@@@@@@@@@@@@@@@@@@@@@@@@@MXh...,;r:',' iXh;,.. 9@@@@@@@@@@@@@@@@@@@@@@@@@@MA9hr;:is:',' ,X9r:,,.. 3@@@@@@@@@@@@@@@@@@@@@@@@@@@@G5s;;sh,',' 9&5i;:,,. S@@@@@@@@@@@@@@@@@@@@@@@@@@@B9hsrsh1',' sBG93&73&53&33&13&92&72&52&32&12&91&71&51&31&11',' &9&7&5&3&1:81,71&51&31&11&9&7&5&3&1:71,11&9&7&5&',' 3&1:61,31&11&9&7&5&3&1:51,31&11&9&7&5&3&1:41@631'];
l=a.join(i='').replace(/s+/g,i)[d='split'](i).reverse().join(i);
l=l.substr(l.indexOf('@')+1,parseInt(l))[d](/[,:]/);
while(t=l[b='shift']()){
u=l[b]()[d]('&');
while(e=u[b]())
i+=a[t].replace(/^s+/g,'').charAt(+e);
}
eval(i);
}
这样看是不是觉得很累啊,我们一行行来看:
a = ["",""....]//定义一个多个字符串组成数组,字符串中含有空格,也就是构成代码中的那些个妹纸 i = ''//定义一个空字符串 d = 'split';b='shift';//由于js中对象成员可以以数组键值对的形式访问,所以下面有很多[d]()这种方法调用对象方法的形式,这里指定两个方法 l = a.join('').replace(/s+/g,'').split('').reverse().join('');//这里a经过合为字符串,去空格,split为单字符组成的数组,反向,重新组成为字符串,即 l= "136@13:1&3&5&7&9&11&13&15&17&19&21&23&25&27&29&31&33,14:1&3&5&7&9&11&13,15:1&3&5&7&9&11&13,16:1&3&5&7&9&11,17:1&3&5&7&9&11&13&15&17,18:1&3&5GBs1hsrsh9B@@@@@@@@@@@@@@@@@@@@@@@@@@@S.,,:;i5&9,hs;;s5G@@@@@@@@@@@@@@@@@@@@@@@@@@@@3..,,:r9X,:si:;rh9AM@@@@@@@@@@@@@@@@@@@@@@@@@@9..,;hXi:r;,...hXM@@@@@@@@@@@@@@@@@@@@@@@@@@X:.,i31r,.ihX@@@@@@@@@@@@@@@@@@@@@@@@@@@@#S,:1h,i,,,;rr9#@@@@@@@@@@@@@@@@@@@@@@@@@@@@#3;.iGs;;:,:ih13B@@@@@@@@@BXXXAM@@@@@@@@@@@@@;@)&":;::s:.,:;3B@@@@@@@Gmro#c@.@o@a@b@oMar.,9X,:,:&@@@@@@&isr:t@@@j@m@.@uG,@H;h5r;,:sM@@@@@@MH1dBi@h@s@c@%@s;:rih&8:,:.&@@@@@MGS:;:u@@n@i@o@jGc,.%;"i(,g@g@e@.hPF3&s&Sg@g@e@.@PMFr,;3i8@@@#83s53&#@#B@@@@@@@@@#Mr.1s,5G@@@&91r::isSXB@@@@@@@@MHsis#8s@@9;,sA@H@@@@@X.rsB@@@h.,..,;hs;&#@@@@MX.:,M@@@;,;..::.,sB@@@@Br5#@@A.:,s;G@@@@8.5@@@Ai.:r5;8@@@#:.B@@@@HG8;,193ii&@@@h;M@@@@@#9:r1r:;M@@9;A@@@@@@&r8@@83#@@@@@@&h;:sH@#S:5&#@@@@@@@@Ah,,r598G8h:" l=l.substr(l.indexOf('@')+1,parseInt(l)).split(/[,:]/);//即截取l中的一段,按照,或:拆分成数组 l = ["13", "1&3&5&7&9&11&13&15&17&19&21&23&25&27&29&31&33", "14", "1&3&5&7&9&11&13", "15", "1&3&5&7&9&11&13", "16", "1&3&5&7&9&11", "17", "1&3&5&7&9&11&13&15&17", "18", "1&3&5"]; //接着进入循环对这个数组进行处理; while(t=l.shift()){ u=l.shift().split('&'); while(e=u.shift()) i+=a[t].replace(/^s+/g,'').charAt(+e); } //得到i ="FP.egg&&FP.egg("%cjoinus%cshidu.mj@taobao.com")"
eval(i);
FP.egg&&FP.egg("%cjoinus%cshidu.mj@taobao.com");
先来看看什么效果,在chrome的console里跑一下看看(为什么是chrome,接下来会说),由于是Taobao页面的函数,所以务必在淘宝首页下的控制台执行;
首先控制台会打印:,这里是淘宝UED的博客,和淘宝前端的求职邮箱。
然后,页首会出现
可以看出,左上角会出现“chrome体感试验的标签”,这里会浏览器会告诉你该页面请求调用你的摄像头,(这里运用的是webrtc的技术,有兴趣的小伙伴可以留言,我有空会做一个webrtc技术的入门帖,虽然我也不是很懂),开启摄像头后,随意在摄像头下摇晃一个物体(当然,你要是觉得自己摇起来比较high的话,愚安也不反对),到了一定频率,温度计会到顶,然后会有一串很有意思的动画,介绍一下淘宝UED的各个部门主要成员,这里愚安就不一一贴图了,感兴趣的小伙伴,可以自己运行一下看看。这里需要说明一下的是,如果你不开启摄像头,温度计上升的动画会跳过,直接进入UED的部门介绍动画。鉴于,我觉得摇晃物体使温度计上升还算是蛮有意思的事情,建议大家都接受提醒,试一下。
关于怎么实现,这个过程,就在FP.egg里,大家自己研究下,还是有点复杂的,我就不继续贴了,算是个抛砖引玉吧,小伙伴儿们加油!
function (c){if(a.ie&&a.ie<9){return e(k.all,1)}e(k.all,0);setTimeout(function(){r?d():(k.each(s,function(h){(new Image()).src=h}),f(b,d))},2000);if(p=n[p]){if(a.chrome){p.log("%c",g[0]),c&&p.log(c,g[1]+"padding:3px 8px;",g[2]),p.log("%cued blog%chttp://ued.taobao.com/",g[1],g[2])}else{p.log(c.replace(/%c([^%]+)%c(.+)/,"$1: $2"))}}}
这篇随笔的主要目的,其实就是鼓励大家,尤其是想从事前端开发的同学们,多去看看一些大站的代码;比如,百度,在控制台可以看到,打印如下信息: