谈一谈支持cross-browser的解决方案
昨天说了说我对于dhtml开发中cross-browser支持的问题,那么我们怎么来最经济实惠的实现cross-browser呢?当然这里就不讨论是否有条件或有必要来做了问题了,昨天已经详细说过我的观点了,而这里只是从dhtml开发本身上来看。
首先我们知道由于JavaScript是解释性的语言,而我们说的支持脚本cross-browser运行,只是我们对于不同browser中相同功能不同interface调用的一个route处理。
举个例子来说,比如我们需要在IE和Mozilla中使用高级事件绑定这个功能。它们在IE和Mozilla中的调用界面分别是:element.attachEvent(eventName, eventHandle)和element.addEventListener(eventName, eventHandle, bCapture)。注意这里两个eventName是不同的,IE的eventName总是"on"开头。那么为了支持cross-browser,我们必须在代码中检测浏览器的类型和版本(THIN给出了一个这样的类),事件绑定代码就应该这样来编写:
if ( isIE )
{
element.attachEvent('onclick', eventHandle);
}
if ( isMozilla )
{
element.addEventListener('click', eventHandle, false);
}
if ( otherBrowser )
{
// ...
}
{
element.attachEvent('onclick', eventHandle);
}
if ( isMozilla )
{
element.addEventListener('click', eventHandle, false);
}
if ( otherBrowser )
{
// ...
}
不管程序在浏览器里会执行那个分支,效果都是相同的。这就是program interface的route,也就是cross-browser的基础,当然这并不是唯一的办法。
现在我们也来把dhtml开发简单的分一下类。一类是最简单的dhtml开发,比如表单验证、ad控制、简单特效(就是不影响页面功能的特效),它们的特点是没有复杂的UI修改和控制;第二类是逻辑较复杂的dhtml开发,比如Gmail、MyMsn啥的,虽然他们的UI变化也挺大,但是逻辑的复杂才是他们最重要的地方;第三类就是UI异常复杂并且细节问题很多的dhtml开发,代表就是bindows类库这样的东西。
前面说了方法调用interface的route是一个解决办法,另一个办法是编写分别支持各种browser的代码,然后通过服务器动态发回和客户端browser匹配的代码版本。对于我们前面的分类来看,第一类和第二类dhtml开发比较适合使用第一种interface route的方式来解决,这里有一个叫做x-lib的开源项目在做这个事情。x-lib的原理就是封装了所有的interface route,然后使用xMethodName来代替所有的dhtml操作,非常像多数据库支持的那种分层设计方式。既然有了这么好的东西,我们为什么不使用它来支持所有的cross-browser开发呢?我们来看一个x-lib封装的xLeft例子:
// xLeft, Copyright 2001-2005 Michael Foster (Cross-Browser.com)
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL
function xLeft(e, iX)
{
if(!(e=xGetElementById(e))) return 0;
var css=xDef(e.style);
if (css && xStr(e.style.left)) {
if(xNum(iX)) e.style.left=iX+'px';
else {
iX=parseInt(e.style.left);
if(isNaN(iX)) iX=0;
}
}
else if(css && xDef(e.style.pixelLeft)) {
if(xNum(iX)) e.style.pixelLeft=iX;
else iX=e.style.pixelLeft;
}
return iX;
}
// Part of X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL
function xLeft(e, iX)
{
if(!(e=xGetElementById(e))) return 0;
var css=xDef(e.style);
if (css && xStr(e.style.left)) {
if(xNum(iX)) e.style.left=iX+'px';
else {
iX=parseInt(e.style.left);
if(isNaN(iX)) iX=0;
}
}
else if(css && xDef(e.style.pixelLeft)) {
if(xNum(iX)) e.style.pixelLeft=iX;
else iX=e.style.pixelLeft;
}
return iX;
}
我们可以看到,为了设置一个style.pixelLeft属性,这个方法还调用了4个x开头的方法(也就是x-lib封装的方法)。由于JavaScript本身作为解释语言的效率就不高,做了一层如此厚重的封装后,使用虽然方便了,但是效率确实也打了不少的折扣。不过对于第一类和大部分的第二类dhtml开发,这个效率损耗因该是可以接受的。这样一来,这样一个x-lib的解决方案就能解决大多数的cross-browser需求。
至于分别实现不同的代码,最大的好处,除了调试上比较方便外,就是能保证效率。我开始说到的bindows就是使用分别编写,针对不同browser的代码这样来做的。其实我这里不是说要达到bindows这样的一个整体开发规模,而是说使用dhtml做大量的细微控制,bindows类库中最消耗资源的运算就是layout。这样的操作如果再封装几层,开发似乎方便了,不过运行起来那个速度就让人抓狂了。这样的解决方案来开发,除了开发成本成倍(由于已经有了一个实现,这个倍数是小于1的)增加外。还有一个问题,就是服务器端判断客户端的类型不是一个绝对准确的方法。因为browser的类型一般是通过http-agent的值来判断的,而http-agent是一段描述性的文字,没有任何的格式保证,所以很可能有判断出错的可能,那么发回客户端的代码的代码就可能和浏览器不能匹配。
posted on 2005-05-30 12:28 birdshome 阅读(3534) 评论(7) 编辑 收藏 举报