“返回顶部”的应用相当广泛,在典型的超长页面里,它几乎是必须的。比如新浪微博里,页面的长度因数据的加载而长达数千像素,它的“返回顶部”并没有太多特别之处,唯一有趣的是那个向上箭头是有两个字符组合而成而并非图片。正是这种细微之处,体现了前端的创想力以及对页面性能的进益求精。
虽然我的题目是插件,但其实内容多半和插件没半毛钱关系…
“返回顶部”的应用相当广泛,在典型的超长页面里,它几乎是必须的。比如新浪微博里,页面的长度因数据的加载而长达数千像素,它的“返回顶部”并没有太多特别之处,唯一有趣的是那个向上箭头是有两个字符组合而成而并非图片。正是这种细微之处,体现了前端的创想力以及对页面性能的进益求精。
虽然我的题目是插件,但其实内容多半和插件没半毛钱关系…
最近有空可以让我静下心来看看各种代码,function与感叹号的频繁出现,让我回想起2个月前我回杭州最后参加团队会议的时候,@西子剑影抛出的一样的问题:如果在function之前加上感叹号 (!) 会怎么样?比如下面的代码:
!function(){alert('iifksp')}() // true
在控制台运行后得到的值时true,为什么是true这很容易理解,因为这个匿名函数没有返回值,默认返回的就是undefined,求反的结果很自然的就是true。所以问题并不在于结果值,而是在于,为什么求反操作能够让一个匿名函数的自调变的合法?
QR code
QR code ,Quick Response code,是一种流行的2维条形码,能够存储多达4296个字母数字字符的任意文本,对于汉字,做多存储1817个,相对于177×177这么小一块区域来说容量已经相当高,更重要的是读取速度——准确而高效,因而在各个领域都有非常广泛的应该。导致现在手机读取条码软件也是相当流行。
Google Chart API 里就有专门的 QR code 生成调用,能非常方便的获取自己想要的 QR code。配图的内容为 swordair.com,长宽为150px,由google生成,看起来还挺不错挺蛋疼的。 如果只是随便玩一下,网络上也有在线的QR code 生成工具,使用起来更加便捷。
问题在于,我们拿着这幅自己完全看不懂的图做什么?用来写情书吗?恐怕是个不错的主意,绕这么多圈子想不收卡都难了,哈哈。
难得闲来无事,对此API我就简单封装了一个QRcode.js,方便日常使用。好吧,我常常写情书,而且一写就停不下来:)
当然,卡也就没少收了…
起初今天碰到的字符串拼接的性能问题并不是关于JavaScript的,而是有关PHP的,名为PHP中的高性能字符串连接( High-Performance String Concatenation in PHP )。众所周知,PHP是用“点”来连接字符串的:
$str = 'a' . 'b'; $str .= 'c';
并且和JavaScript类似,PHP也可以通过Array来拼接字符串:
$str = implode(array('a', 'b', 'c'));
问题就是,当拼接达到上万的数量级之后,哪一种性能更好呢?
这段时间,怿飞的博客上有一篇用 JavaScript 解数学题,代码很简练优雅。于是突然想用C写写看,因为很久没写,就权当是练习也挺不错啊:)
题目是这样的:一个六位数,分别用2,3,4,5,6乘它,得到的五个新数仍是由原数中的六个数字组成,只是位置不同,则此六位数是多少?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | #include <stdio.h> #include <string.h> #define DIGIT 6 #define MULTI 5 void swap( char *a, char *b ){ int tmp; tmp = *a; *a = *b; *b = tmp; } void bubbleSort( char arr[] ) { int i,j; for(i = 0; i < DIGIT; i++){ for(j = 0; j < DIGIT-1; j++){ if ( arr[j] > arr[j+1] ){ swap( arr+j, arr+j+1 ); } } } } int main(){ int num, numCopy, i, j, ind; int mul[MULTI] = {2,3,4,5,6}; char indStr[DIGIT+1]; char StrToCmp[DIGIT+1]; for( num = 1000000/6; num >= 100000; num-- ){ numCopy = num; for( i = 0; i < DIGIT; i++ ){ StrToCmp[i] = numCopy%10+48; numCopy /= 10; } StrToCmp[DIGIT] = '\0'; bubbleSort( StrToCmp ); for( i = 0; i < MULTI; i++ ){ ind = num * mul[i]; for( j = 0; j < DIGIT; j++){ indStr[j] = ind%10 + 48; ind /= 10; } indStr[DIGIT] = '\0'; bubbleSort( indStr ); if( strcmp( StrToCmp, indStr )){ j = 0; break; } } if(j){ printf( "This number is %d\n", num ); } } getchar(); return 0; } |
PureMVC不仅仅是AS的经典MVC模式的框架,同时也有其他语言的实现,比如JS,php,C#。我接触PureMVC也只是这半年里的事,伴随着一个项目应用了这个边学边用的AS3框架。PureMVC很容易使用,那时我参考的是Cliff Hall的Best Practices,例子讲述了一个使用PureMVC的登陆过程。非常详细,而且很多注意点提示地都非常深刻。
如果查看Flex的框架源码,就经常会看到有些属性和方法被加上了 mx_internal 前缀。特别是调试的时候。于是就自然要去查找 mx_internal 是什么。Adobe Developer Connection 上,有篇 什么是mx_internal 的文章,大体上说,mx_internal 是一个命名空间,这个命名空间被Flex框架用来划分那些在将来的SDK发布中可能会做更改的方法和属性。
前段时间碰到关于Flex的Base64编码的问题,今天打算写个小节。
最早认识的AS3编码类是com.dynamicflash.util.Base64,这个类可以从http://dynamicflash.com/goodies/base64/下载到。当前的直接下载链接是Base64-1.1.0.zip。
查看源代码,这是一个非常简约的类,111行代码整洁而优雅。具体使用也非常简单,将build里的as3base64.swc放到libs目录里将其导入到工程,直接调用其静态方法后就返回了想要的结果。
1 2 3 4 5 6 7 8 | import com.dynamicflash.util.Base64; var source:String = "Hello, world!"; var encoded:String = Base64.encode(source); trace(encoded) var decoded:String = Base64.decode(encoded); trace(decoded); |
使用Flash Media Live Encoder ,可以非常方便的录制直播视频(live video)。Flash Media Live Encoder 的选项很多而且很细,品质控制也很不错。如何在AS3中实现这些?
参考FMS的Help,我简单的封装了这样一个类:
1 2 3 4 5 6 7 8 9 10 11 12 | package com.swordair.as3 { /** * * @author iifksp * */ import flash.events.NetStatusEvent; import flash.media.Camera; import flash.media.Microphone; import flash.net.NetConnection; import flash.net.NetStream; |
这段短短50行的JS滑动窗效果,算是我的第二次JS编写(2009-04-06)。最后作为了毕业论文网站的一个小插曲。
122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 | <script type="text/javascript"> var currentTab = "tab_1"; var widthUnit = 670; var maxTab = 7; function srollArrow(direction,scrollSection){ if(direction=="left"){ if(currentTab.split("_")[1]=="1"){ nextTab = "tab_"+maxTab; }else{ var nextTabNum = parseInt(currentTab.split("_")[1])-1; nextTab = "tab_"+nextTabNum; } scrollTab(nextTab,scrollSection); }else{ if(currentTab.split("_")[1]==maxTab){ nextTab = "tab_1"; }else{ var nextTabNum = parseInt(currentTab.split("_")[1])+1; nextTab = "tab_"+nextTabNum; } scrollTab(nextTab,scrollSection); } } var moveManager = {begin:0, end:0, change:0 ,finalPos:0 , time:18.0, limit:8.0}; function scrollTab(tabName,scrollContent){ if(currentTab == tabName){ return; } lastTab = currentTab; currentTab = tabName; document.getElementById(currentTab).className = "active"; document.getElementById(lastTab).className = "inactive"; moveManager.begin = parseInt(lastTab.split("_")[1]); moveManager.end = parseInt(currentTab.split("_")[1]); moveManager.change = (moveManager.begin - moveManager.end)*widthUnit; moveManager.finalPos = -(moveManager.end-1)*widthUnit; oScrollContent = document.getElementById(scrollContent); nowLeft = parseInt(oScrollContent.style.left); move(); } function move(){ if(moveManager.time<=moveManager.limit){ oScrollContent.style.left = moveManager.finalPos + "px"; moveManager.time = 18.0; return; } nowLeft += parseInt(moveManager.change*1/moveManager.time); moveManager.time-=0.9; oScrollContent.style.left = nowLeft + "px"; setTimeout("move()",15); } </script> |