• 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的压缩工具很多,例如:JSMinYUI 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