-
Javascript(Ajax)开发测试工具
IDEs
NetBeans, IntelliJ, 以及 Eclipse 等ide都内置或者插件支持javascript的编辑开发。eclipse的插件很丰富,我个人认为 aptana 的html/css/javascript开发插件做的比较专业。
Firebug
这个鼎鼎大名的firefox插件不用多说。它的出现是划时代的。用作者的一句话说就是”开发web应用没有firebu就像用vi编写java代码–虽然可以完成,但不值得忍受这样的痛苦”。
Firebug Lite
Firebug Lite 是为非firefox的浏览器准备的。只需要在页面里包含一个js,就可以在其他浏览器中享受firebug带来的便利。或者把它作为一个bookmarklet收藏到收藏夹里,在需要调试的页面运行就可以。
YSlow
YSlow是一个firebug的插件,由Yahoo!的开发团队开发。用来给网页提供优化建议。
Hammerhead
Hammerhead 是个检测网页加载速度以及提供便利的清空cache操作的firefox插件。
测试JavaScript 代码
JsUnit
JsUnit是一个javascript测试框架,类似于java中的JUnit。它提供一个**JsUnit Server, **这样你可以把JsUnit tests 并入你的 continuous-integration (CI) server,在服务器端用JUnit或者Ant脚本测试Javascript。它提供跨浏览器跨系统的javascript测试。
JSSpec
JSSpec将 BDD(behavior driven development)带入了Javascript。可用来进行Javascript的无人职守测试,不过它只能在浏览器中运行。
YUI Test
YUI Test 是一个javascript测试世界里的新成员。和JsUnit和JSSpec不同的是,YUI Test允许你模拟基本的用户行为 例如鼠标点击和键盘事件,它允许暂停测试,等待对服务器的异步请求返回结果。
Crosscheck
Crosscheck,顾名思义,它是检查javascript跨平台功能的一个程序。它运行在JVM之上,不需要启动浏览器就可以进行测试。因为它内部模拟了各种的 浏览器/操作系统 组合。
测试UI
Selenium
Selenium 是ThoughtWorks开发的一款web测试工具,是一个firefox插件。它可以记录鼠标点击,键盘键入等用户操作用于测试。你还可以在浏览器中进行回放。
Watir
Watir是ThoughtWorks开发的另一款web测试工具,是专门为quality-assurance (QA)人员开发的工具。
其他小工具
JSLint
JSLint可以检查你的javascript代码,然后找出其中的错误或者不良操作并给出修改建议。
压缩工具
Javascript的压缩工具很多,例如:JSMin 和 YUI Compressor
文档工具
Javascript虽然没有类似于Java Doc的标准,但也有类似的替代品。如Prototype 的 PDoc, YUI 的 YUI Doc 。
结论
JavaScript开发地位越来越重要,不应该让JavaScript的开发降级到用alert和文字编辑器的程度。今天,我们有IDE的自动完成,全方位的调试工具,以及各种测试工具。 今天,JavaScript在任何Web应用中都是一流公民,JavaScript开发者应该有世界一流的开发工具用来制作世界一流的互动应用。
关于本文
本文是Ajax: Tools of the trade的摘要翻译。原文请参看:
-
参加了一下Android技术大会
大会的名头不小,首届 亚太地区Android技术大会。刚开始我以为是google搞的,结果不是。
随便询问了一下,像我这样自己花钱来参加的寥寥无几。门票400元,幸亏我买的是社区票,280,稍便宜点。
会场给人的感觉就不好,投影仪太小,出现图表干脆就看不清楚,我去的还比较早,在前面坐着。发了本讲义,但讲义上一页印好几页幻灯片,图表还是看不
清楚。后来上来了一个哥们,看着就像做技术的,估计也没怎么讲过课,对着幻灯片上的流程图就开始乌拉乌拉讲,也不管下面的人听明白不。请了一个日本教授,就上去念了一下幻灯片上的英语。还有个韩国的讲师,据说是开发Android的牛人,但英语发音是在太烂,不知所云。
下午一个讲师讲android的多媒体架构,确实不错。
然后一个日本的开发人员给演示了一下几个Android相关的应用。一个叫 Dalvik
VM,好像是在j2me上又加了一层,可以让Android上的应用运行在支持j2me的手机上。一个叫
ikoto,Android上的模拟中国古琴的软件,从屏幕上划过的时候就发出琴弦被拨动的声音,挺好玩。还有一个叫Droidget,运行在
Android上的桌面小控件程序,可以用javascript写控件。 -
javascript库的延迟加载
如果只是简单的让js延迟加载,那只需要在页面尾部加上这样的代码:
var oHead = document.getElementsByTagName('HEAD').item(0); var oScript= document.createElement("script"); oScript.id = id; oScript.type = "text/javascript"; oScript.src=src; oHead.appendChild(oScript);
但这样加载有个问题,如果我立刻在后面调用这个延迟加载的js里面的方法或者变量就会报错,因为新加载的js还没执行完呢。并且document的onload方法不会等待这样的延迟js加载成功。
还有就是这样加载的js不能保证顺序。也就是不能保证先append的js先执行。如果后面的js依赖于前面的js,而前面的js比较大,加载延迟,则后面的js执行的时候就可能报错。
我在修改这个高亮代码的脚本的时候就遇到了这样的问题。
并不是所有的文章都有代码,并且每篇文章可能出现的代码语言不一样,需要根据内容加载不同的库。
shCore.js是核心js,需要先加载。然后是各个语言的js,具体取决于文章内容中出现的代码语言。如 shBrushJava.js,shBrushBash.js等。
后面这些js都依赖于shCore.js。当所有的js都加载完的时候,才能调用:
SyntaxHighlighter.highlight();
高亮代码。
参考了一些文章,终于弄出一个解决方案:
if(!window.BrushUtils) var BrushUtils = (function(){ var ut = { baseurl:"", resources:[], brushMap : {js:"JScript",jscript:"JScript",javascript:"JScript", bash:"Bash",shell:"Bash",css:"Css",actionscript3:"AS3",as3:"AS3",cpp:"Cpp",c:"Cpp", csharp:"CSharp",groovy:"Groovy",java:"Java",javafx:"JavaFX",jfx:"JavaFX", perl:"Perl",pl:"Perl",php:"Php",text:"Plain",plain:"Plain",py:"Python",python:"Python", ruby:"Ruby",ror:"Ruby",rails:"Ruby",scala:"Scala",sql:"Sql",xml:"Xml",html:"Xml",xhtml:"Xml",xslt:"Xml" }, parseBrush :function(){ var pres = document.getElementsByTagName("pre"); var brushs = new Array(); for(var i=0;i0?function(){ut.loadNext();}:function(){SyntaxHighlighter.config.clipboardSwf = ut.baseurl 'scripts/clipboard.swf';SyntaxHighlighter.highlight();}; if(resource.type=='js'){ ut.loadJs(resource.url,callback); }else if(resource.type='css'){ ut.loadStyle(resource.url,callback); } } }, loadJs : function(src,callback){ var scriptTags = document.getElementsByTagName('script'); var oHead = document.getElementsByTagName('HEAD').item(0); var script= document.createElement("script"); script.type = "text/javascript"; script.src=src; script.onreadystatechange= function () { if (this.readyState == 'loaded' || this.readyState == 'complete') { callback(); } } script.onload= callback; oHead.appendChild(script); }, loadStyle : function(url){ var oHead = document.getElementsByTagName('HEAD').item(0); var style= document.createElement("link"); style.type = "text/css"; style.rel="stylesheet"; style.href=url; oHead.appendChild(style); } }; return ut; })();
调用:
var syntaxhighlighter_url = "/scripts/syntaxhighlighter/"; BrushUtils.loadLibs(syntaxhighlighter_url);
主要在于对script的加载成功事件的监听。ie的事件是onreadystatechange,firefox的是onload.把需要加载的js放在一个队列里,当前一个加载完成时候,从队列里取出下一个js,继续加载。
经过测试,这个方法在ie,firefox,opera上都可以使用。但据说Safari上是没这个事件的(未测试)。
本来想给样式表也加上事件监听,结果发现样式表加载成功在firefox下是不触发事件的,ie下可以。
参考网址:
http://unixpapa.com/js/dyna.html
-
搜索引擎URI编码的处理
做一个站内搜索遇到一个问题:
网站全站使用的是UTF-8编码,所以get请求的URL也用UTF-8编码,服务器端用UTF-8解码。这种情况下,用户直接在表单里输入提交过来搜索,是没有问题的。但如果用户直接在浏览器地址栏里把关键词给改了,提交过来,或者从浏览器地址栏的下拉提示列表里点击过来,URL编码就不确定了。这个和操作系统语言以及浏览器相关。
ie默认情况下,对在地址栏里输入的URL路径里的中文是用utf-8编码的,但对get参数不会自动编码,会直接把原始字符串发过去。
其他浏览器都会对地址栏里输入的get参数进行编码,编码方式和操作系统环境语言相关。
Read more... -
linux下文件名特殊符号导致的一个诡异问题
写了个bash脚本递归循环遍历文件夹。本地测试的好好的,结果传到服务器上就不行,一直死循环。以为是linux的版本问题,折腾了半天,才发现只有遍历特定那个文件夹的时候才会出现问题。
最后发现竟然有个文件夹的名字叫
当遍历到文件夹的时候,路径就成为 /home/image/
而符号在bash里是转义符号,必须用/home/image/\才行, /home/image/表示的还是 /home/image/。所以导致死循环了。
然后又实验了一下,linux下的文件夹没有限制字符,所有的可打印字符都可以作文件夹名。比方
*,,|,等在windows下是不允许做文件夹名的,但linux下就可以。但这样的文件名确实会给用户造成迷惑。比方一个叫
*的文件夹,用户如果删除的时候忘记转义,输出成 rm -rf *,那就惨了。不知道linux的设计者为什么没考虑到这个问题?或者说考虑到了,但觉得这样的问题应该让用户自己掌控?
-
css强制换行问题
1.(IE浏览器)连续的英文字符和阿拉伯数字,使用word-wrap : break-word ;或者word-break:break-all;实现强制断行
#wrap{word-break:break-all; width:200px;}
或者
#wrap{word-wrap:break-word; width:200px;}abcdefghijklmnabcdefghijklmnabcdefghijklmn111111111
效果:可以实现换行
2.(Firefox浏览器)连续的英文字符和阿拉伯数字的断行,Firefox的所有版本的没有解决这个问题,我们只有让超出边界的字符隐藏或者,给容器添加滚动条
#wrap{word-break:break-all; width:200px; overflow:auto;}
abcdefghijklmnabcdefghijklmnabcdefghijklmn111111111
firefox下的一个解决方法:
XBL binding
.wordwrap { -moz-binding: url('./wordwrap.xml#wordwrap'); }
wordwrap.xml的内容:
//
演示地址:http://ecmascript.stchur.com/blogcode/emulating_word_wrap_take2/
如果要通用的,跨浏览器的解决方案就只能用javascript
//aka makeDesignerHappy(dEl); function breakWord(dEl){ if(!dEl || dEl.nodeType !== 1){ return false; } else if(dEl.currentStyle && typeof dEl.currentStyle.wordBreak === 'string'){ //Lazy Function Definition Pattern, Peter's Blog //From http://peter.michaux.ca/article/3556 breakWord = function(dEl){ //For Internet Explorer dEl.runtimeStyle.wordBreak = 'break-all'; return true; } return breakWord(dEl); }else if(document.createTreeWalker){ //Faster Trim in Javascript, Flagrant Badassery //http://blog.stevenlevithan.com/archives/faster-trim-javascript var trim = function (str) { str = str.replace(/^ss*/, ''); var ws = /s/, i = str.length; while (ws.test(str.charAt(--i))); return str.slice(0, i 1); } //Lazy Function Definition Pattern, Peter's Blog //From http://peter.michaux.ca/article/3556 breakWord = function(dEl){ //For Opera, Safari, and Firefox var dWalker = document.createTreeWalker(dEl, NodeFilter.SHOW_TEXT, null, false); var node,s,c = String.fromCharCode('8203'); while (dWalker.nextNode()) { node = dWalker.currentNode; //we need to trim String otherwise Firefox will display //incorect text-indent with space characters s = trim( node.nodeValue ) .split('').join(c); node.nodeValue = s; } return true; } return breakWord(dEl); }else{ return false; } }
以上代码来自下面这个网址:
subscribe via RSS