Feb 26, 2009

可持续访问的AJAX

《ppk on Javascript》书中谈到Javascript的目的,Javascript其实是为web增加特别的一层可用性,我的理解Javascript的在web中的角色是增加web的易用性,让用户更好的体验web产品,开发者在设计产品时,就应该考虑到不同用户的复杂情况,例如禁用脚本的用户、盲人、手持设备用户等等。

创建可持续访问性的web,也可以如上理解,具体在开发中的细节如下:

  • a链接一定有href地址,页面分离事件注册器,决绝行内时间注册(例如<a href="#" onclick="func();">)
  • 有选择性的使用Javascript和CSS隐藏页面内容1
  • 不用Javascript做页面跳转,否则用户使用浏览器的后腿按钮将无限制跳转,最终只能强迫用户推出页面,这样的体验真的很糟糕,我想至少我收够了这样的方式;
  • 务必考虑脚本兼容主流的浏览器,招商银行的网银和之前淘宝的支付宝不支持Firefox就是例子,用户抱怨很囧

另外,记录一下以前开发中的小技巧:

当我们希望点击一个a链接,然后用一个DIV的popup容器来呈现内容而不刷新页面时,使用AJAX如果做到持续的可访问性呢?首先,来思考一下无脚本的情况下,这个a链接的地址一定是能够访问的,访问的页面应该是完整的页面(有head和foot),而不是HTML片段。然后,再思考一下有脚本情况下,我们给a链接注册一个事件func,事件func完成一个AJAX请求,把a链接的href地址通过异步获取到当前页面,并且创建一个DIV作为popup容器,那么这个popup容器内被请求的HTML不应该显示head和foot部分(HTML片段)。那么,现在的问题是,如果判断当a链接分别在有脚本、无脚本的的情况下,显示或者不显示页面的head、foot部分呢?如下:

当脚本可用时,我们在func里给a链接加上一个参数"popup":

<a href="http://www.site.com/site.php">Click</a>//页面静态地址
<a href="http://www.site.com/site.php?popup=1">Click</a>//JS给a href添加“&popup=1”

那么现在当为AJAX请求页面时,a href带有一个popup=1的参数,当无脚本时,a href无popup=1的参数,这个参数有什么用呢?popup=1这个参数可以交给服务器脚本,服务器脚本判断当页面上有popup这个值时,就不编译head和foot的HTML,没有这个popup这个值,服务器脚本就编译head和foot的值。

以上这种方法,美味书签用到很多,有兴趣的可以登录体验一下美味书签的一些操作(删除、编辑),操作方法就是禁用脚本,或者对美味书签的删除、编辑按钮用新窗口打开。

有选择性的选择JS或者CSS隐藏内容,分情况例如:JS驱动的下拉菜单,禁用脚本用户是无法浏览到被隐藏的菜单,那么菜单的隐藏内容应该用JS隐藏,当无脚本的情况下,JS隐藏菜单的功能自然也无法工作,那么禁用脚本的用户自然也可以浏览到本该隐藏的菜单列表

Feb 23, 2009

弄懂IE的haslayout(二)

IE6中,如果list的子节点display为block属性,IE6会把HTML文档中的换行符呈现出来,以至于list之间出现空白的间隔,代码如下:

<style type="text/css">
* {margin:0;padding:0;}
li {list-style:none;}
li span {
  display: block;
  background-color:#f1f1f1;
  zoom:1; /*去掉zoom属性,查看IE6下span的haslayout值*/
}
</style>

<ul>
  <li><span>link items</span></li>
  <li><span>link items</span></li>
  <li><span>link items</span></li>
</ul>

Feb 22, 2009

获取鼠标位置

获取鼠标位置,就是获取event对象的坐标属性,先看看如何获取event对象。在W3C的模型中,把参数传递的第一个参数当作当前的event对象,在MSIE的模型中,总是window.event。

function myfunc(e) {
  var e = e || window.event;//如果e不存在,则获取window.event
}

event对象的坐标属性pageX, pageY分别是当前鼠标相对body的X, Y的坐标值,但是在IE中没有pageX和pageY,不过可以通过clientX, clientY加上scrollTop, scrollLeft的值来确定当前鼠标的位置。clientX, clientY是当前鼠标相对window的坐标值。代码:

function mouseCoords(e){
 if(e.pageX || e.pageY){//标准浏览器返回当前鼠标坐标值
  return {x:e.pageX, y:e.pageY};
 }
 else if(e.clientX || e.clientY) {//仅IE返回回当前鼠标坐标值
  return {
   x:(e.clientX + document.documentElement.scrollLeft + document.body.scrollLeft),
   y:(e.clientY + document.documentElement.scrollTop  + document.body.scrollTop)
  }
 }
}
function mouseMove(e){
 e = e || window.event;
 var mousePos = mouseCoords(e);//这里mousePos.x, mousePos.y分别为鼠标的X, Y坐标值
}

以上代码中发现一个兼容性问题,如果文档声明为XHTML,document.body.scrollTop的值始终为0,所以在XHTML文档声明的时候,只能用document.documentElement.scrollTop。

Feb 19, 2009

爸妈学电脑

我真的没想到,难倒爸妈学习电脑,不是windows操作系统的各种按钮以及各种术语,也不是windows的难以理解的文件管理系统。真正让他们头疼的是密密麻麻的键盘和难以操作的双键鼠标

爸妈两个人几乎都无法适应鼠标的两个键操作,经常误击鼠标的右键。教他们的同时,我不得不想到苹果电脑的单键鼠标。80年代Apple公司的GUI操作系统及Windows的视窗普及之后,鼠标也随着普及,80年代至今,鼠标经历了滑动机械鼠标、光电鼠标等等。当然鼠标的形状及手感也越来越舒适,可是鼠标上的按键越来越复杂。这也怪不了我的爸妈用起来鼠标来那么吃力,苹果电脑的单键鼠标这么多年,从OS 8.6已经支持鼠标右键菜单,可是苹果一直随箱附送单键鼠标,这里有一篇文章很有意思,可见苹果的设计师很多年前就碰到过我爸妈这样的用户。

Feb 16, 2009

弄懂IE的haslayout(一)

haslayout到底是什么?

haslayout是IE的私有概念,HTML部分元素默认拥有haslayout,而通过部分的CSS,可以给haslayout不为true的HTML元素触发为true。也就是说,如果某个HTML元素拥有haslayout属性,那么这个元素的haslayout的值一定只有true,否则,这个元素就没有haslayout,haslayout一旦被触发,就不可以逆转,haslayout为只读属性。

查看haslayout的值

通过IE Developer Toolbar可以查看IE下HTML元素是否拥有haslayout,在IE Developer Toolbar下,拥有haslayout的元素,通常显示为“haslayout = -1”。

那些HTML元素默认拥有haslayout?

<html>, <body>
<table>, <tr>, <th>, <td>
<img>
<hr>
<input>, <select>, <textarea>, <button>
<iframe>, <embed>, <object>, <applet>
<marquee>

在IE下,哪些CSS属性可以触发haslayout为true?

IE6:
position: absolute, float: left|right, display: inline-block, width: 任意值, height: 任意值, zoom: 任意值
IE7:
overflow: hidden|scroll|auto, position: fixed, min-width: 任意值, max-width: 除 none 之外的任意值, min-height: 任意值, max-height: 除 none 之外的任意值

那么,了解haslayout有何意义呢?haslayout可以解决IE很多奇怪的bug和渲染bug,通常通过触发haslayout为true来解决。接下来,就了解下因为haslayout的临床表现:

  • 负边框问题,下载这个demo然后去掉IE6注释,对比标准浏览器和IE6下不同的表现,并且用IE develop toolbar查看不同表现的HTML元素的haslayout。
  • 滤镜,IE的私有滤镜只有在元素被触发haslayout后,滤镜才会被执行。

未完待续。。。