overflow:hidden带来的问题

即时更新:@drunber提供的解决办法:设置父元素的padding或者border、float、position:absolute也可以解决问题,经测试验证通过。但是有一点需要说明的是:上下padding和border是必须要有数值的,设置为0无效。

但是对于动画来说,overflow:hidden是必须要设置的,否则里面的文本不会被遮盖。

———===========—– 即时更新分界线 ——===========———–

最近接到个需求,在搜索结果中添加下拉动画,高度和透明度都需要渐变。在测试过程中,遇到这样的一个问题:在一个div容器中包含了几个p标签,而且全在默认样式的情况,这样通过offsetHeight,clientWidth,scrollHeight等等获得div的高度,之后动态设置div的overflow样式属性为hidden,这样上面所获得的高度不准确了,《点击测试吧》,这样的后果就是动画被和谐了。

从这里的overflow:hidden对div的高度的差异可以看出:容器包含内容的解析原理。正常默认情况下,比如div包含一个p标签,这样div的宽高是会忽略p标签默认的margin值;但是一旦给div设置了overflow:hidden之后,div的实际宽高就需要加上p的margin值了。不过值得庆幸的是,在给div设置了overflow:hidden之后,通过offsetHeight等来获取div的宽高,是准确的。

从上面的分析中对于开头遇到的问题,就可以有三种方法来解决了:第一、在动态设置overflow:hidden之后来获取容器的高度,《点点测试吧》;第二、将p标签的margin清0处理,《再点点呗》;第三、干脆就不要使用p标签,改用没有默认margin的div吧,很勉强的方法,《最后点击测试下》。

Tip: 经过测试发现,设置overflow属性为hidden、auto都存在上面所说的情况。

前端模板编程方式

今天接触到一种使用javascript来实现的前端模板编写技巧,不需要后端的匹配替换,直接在浏览器端就可以完成。Not Using jQuery JavaScript Templates? You’re Really Missing Out。觉得思路不错,特此分享。

在浏览器端实现模板编程的难点之一,就是怎么编写HTML模板。这个在那篇文章中使用了script标签,这个觉得非常太神奇了,最神奇的是给script的type设置为text/html之后,它就不会使用javascript引擎来解析那些代码,也不会在页面上将HTML显示出来,同时也不报错。这都被发现了,牛逼!

知道了怎么保存模板之后,接下来的事情就是解析模板了,统一替换变量的声明方式,下面是我样例中使用的方式:

<script id="test" type="text/html">
<li><a href="${url}$">${name}$</a></li>
</script>

之后,就是通过javascript程序来解析了,我简单写了一个template函数来实现这个功能,《测试用例》:

function template(data,sEl,dEl){
  var html = sEl.nodeName && sEl.innerHTML || sEl,s = tmp = "";
  data = data || [];
  for(var i=0,l=data.length;i<l;i++){
    tmp = html;
	for(var k in data[i]){
	  tmp = tmp.replace(RegExp("\\$\\{"+k+"\\}\\$","gi"),data[i][k]);
	}
	s += tmp;
  }
  (dEl = dEl.nodeName && dEl || document.getElementById(dEl)).innerHTML = s;
}

通过上面的解析,在页面中就可以定制模板(特别是那些标题列表内容,即:ul,ol等),通过数据源,在页面中显示出来。当然了,这个在页面开始加载的时候如果就是用这个的话,无疑是多此一举,但是如果是通过动态获取数据(JSON,XML),并且需要将数据在页面中显示出来的时候,这种思路或许可以带上用场,减小代码编写量了,提高效率了。

无聊哥的代码 — “鸡”查询

刚上班,首先是文档哥,之后就是无聊哥了,真杯具。但是杯具下就好了,人不杯具。消遣的最好方式就是练练脑,写代码,query就是杯具下的产物。先出土个雏形,有时间还成无聊哥了再来扩展下。

query根据CSS规则来查询DOM,提供了基础的CSS选择符:

tag,.class,#id,[attr],tag[attr],tag[attr="value"]...

在测试跟jquery的查询速度比较的时候,再添加了对querySelectorAll(语法是:baseElement.querySelectorAll(selector),这里的baseElement其实是可以为除了文本节点和空节点之外的任何的DOM节点的,别以为只是document而已)的支持。编写的代码中加入了本人认为不错的编写方式,如果你对阅读代码有兴趣,那就看看吧,欢迎提出更好的方式(如果这里显得难看了,就自己下载来看:query.js):
(全文…)

Web Worker浅析

2010-8-7 update:很悲剧的发现,Web Worker不支持跨域调用js文件。同时,经过测试,发现在Worker进程中的onmessage函数不能使用function onmessage(){}这种方式来声明,否则chrome、safari、opera不能执行它,切记~(实现Worker,FF比chrome、opera、safari兼容性好多了)

如果你使用window.onmessage=function(){}来声明onmessage方法,FF、Chrome等都提示window未定义的错误,这就很奇怪撂。难道Worker进程中不存在window这个对象?

—————————– 更新分界线 ——————————

javascript单线程任务式的运行代码,这是大家普遍都知道的事情,有时候为了模拟多线程,会使用setTimeout/setInterval的方式,但是这个并不能解决实质的问题。Web Worker — javascript的“多核”时代来了!

Worker也已经出现的比较早了,记得当初首先是在Mozilla网站看到关于它的语法和特点介绍,今天在逛Opera看到了关于它的说明文档:Web Workers rise up!。觉得来详细的分析下它的原理是很有必要的了。下面是我对它的一点点看法:

Web Worker的基本原理就是在当前javascript的主线程中,使用Worker类来独辟一个新的线程,来处理外联的一个javascript文件,起到互不阻塞执行的效果,并且提供主线程和新线程之间数据交换的接口:postMessage,onmessage。而它的数据交换方式有点类似于Ajax的异步请求,都是浏览器“暗地里”传输的。下面是我分析之后得出的一个流程图:

(全文…)

避免丑陋的if逻辑的新技巧

我写代码时对if逻辑是比较反感的,说不出原因,用户体验不爽,因此总会使用三元运算符来规避if逻辑,看起来代码量少,简洁。对于操作单条的代码,这种方式就可以很容易的使用三元运算符来替换,比如:

if(flag){
  doSth();
}else{
  doAnotherSth();
}
//可以替换为:
flag ? doSth() : doAnotherSth();

单条的很容易,但是对于多条操作语句呢?这时候该怎么来避免使用if。答案还是从三元运算符中找,例如:

if(flag){
  c = "ss";
  d ="none";
  e.style.display="block";
}else{
  c = "cc";
  d ="normal";
  e.style.display="none";
}
//这个时候,还是可以通过一点小技巧来实现的:
flag ? ( c = "ss",d="none",e.style.display="block") : (c = "cc",d="normal",e.style.display="none");

各个操作语句之间使用逗号“,”组合起来,再加上小括号,就可以执行了。为此,可以较少一些字节,也使得代码简洁起来。

Watch对象更新

这次对Watch对象添加了一个新方法:iterate。主要是用于这样的情况,同时测试多个指定循环次数的情况,比如可以同时指定1000、2000、3000、4000…等等,通过iterate方法,就可以查看到几个测试用例在这几个循环次数下的时间消耗,iterate的用法如下:

Watch.iterate({
  "title":["getElementsByTagName","childNodes"],
  "loop":[1000,2000,4000,5000,10000,20000,40000,100000],
  "interval":1500,
  "fn":[
    function(){ document.getElementById("div").getElementsByTagName("p");},
    function(){  document.getElementById("div").childNodes;}
  ]
});

iterate方法带有一个对象字面量参数,这个对象字面量的参数的属性包括title数组、loop循环次数数组、interval更新显示的时间间隔、fn测试函数数组。说起来可能比较虚,看例子吧:Watch.iterate()