-
参加了一下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; } }
以上代码来自下面这个网址:
-
Javascript对象中使用setTimeout和setInterval的问题
前两天写一个js时遇到个问题。就是在js对象内部如果用setTimeout或者setInterval调用该对象的一个方法,然后在被调用方法中就无法使用this获取该对象。因为经过setTimeout调用后,this就成了浏览器了,原来那个对象就丢失了。
如:
function TestObj(){ this.property = "test"; this.called = function(){ alert(this.property); } this.setTimeCall = function(){ setTimeout(this.called,500); } } var test = new TestObj(); test.setTimeCall();
如果直接调用test.called方法是没有问题的。但如果通过setTimeout调用,也就是调用
test.setTimeCall(),this.property就为空了。因为这里的this成浏览器了。同样的问题也发生在监听浏览器的其他事件
上。没办法,于是用了个比较糟糕的办法。function TestObj(){ this.property = "test"; this.called = function(){ alert(this.property); } this.setTimeCall = function(){ setTimeout("test.called()",500); } } var test = new TestObj(); test.setTimeCall();
之所以说这样做糟糕,是因为在定义TestObj时,就必须提前知道TestObj被创建时的变量名。后来在IBM社区看到一篇探讨javascript有限状态机的文章,用了一个很巧妙的办法避免这个问题。
function TestObj(){ this.property = "test"; var self = this; this.called = function(){ alert(self.property); } this.setTimeCall = function(){ setTimeout(self.called,500); } } var test = new TestObj(); test.called(); test.setTimeCall();
在TestObj中定义一个变量,self,然后指向this。这样用self调用this,就不会发生和浏览器的this对象冲突的问题了。
虽然是很简单的一个问题,但有时候人脑子转不过弯也没办法。
还有一个网友评论提供的办法就是:
function TestObj(){ this.called = function(){ alert("OK"); } this.setTimeCall = function(){ setTimeout(this.called.bind(this),500); } }
subscribe via RSS