Atlas 学习记录

这一篇记录一些学习 Atlas (不包含 Control Toolkit 的核心框架部分)碰到的问题点:

1)String.format 函数

Atlas 的客户端脚本提供了 String.format 这个我们在 .NET 编程中非常熟悉也非常常用的函数,基本上实现了和 .NET 一致的功能。也支持对数字、日期的格式化(包括标准 patterns 和自定义 patterns)。

而且 String.format 的格式化,和 .NET 中类似,也是和 Culture 相关的,针对不同的 Cultures 显示不同的格式。如: String.format('{0:d}', new Date(2006, 9, 1)) 在 zh-CN 下显示为 2006/10/1,在 en-US 中显示为 10/1/2006

另外,Atlas 中的 Sys.StringBuilder 也很好用。

2)atlasglob.axd 及 globalization

此脚本是虚拟的,动态产生。它负责将特定 Culture 的格式定义传递给客户端脚本,用以支持 String.format 的格式化等功能。

很重要的是,atlasglob.axd 的默认行为是:根据客户端浏览器中设置的首选语言,来决定到底返回哪个 Culture 的格式定义信息。比如,客户端浏览器首选语言为 zh-CN,则不管当前站点使用何种 Culture,(不受当前 Thread.CurrentCulture 的影响),都会自动将 zh-CN 的格式定义信息传递给客户端。这样可能出现不适当的格式显示(例如网站是英文,日期却显示为中文)。[请参见]

atlasglob.axd 可以接受一个名为 c 的 QueryString。例如如果请求 atlasglob.axd?c=zh-CN,则强制性返回 zh-CN 区域的格式定义信息。

由于 Atlas.js 中默认包含的是 en-US 的格式信息,则,如果网站是 en-US 区域的站点,并且不针对其它区域提供国际化服务,则可以考虑将 ScriptManager 的 EnableScriptGlobalization 设置为 false。如果是非 en-US 的站点,则应该考虑显式包含一个 atlasglob.axd?c=zh-CN 以适应 zh-CN 的日期、数字格式化。

另外,因为 atlasglob.axd 不带参数时,默认取浏览器的首选语言;而浏览器(比如 IE)的语言列表和 .NET 支持的 Cultures 列表并不一致,则可能出现一个 bug,即:如果在浏览器中设置首选语言为一个 .NET 不支持的 Culture 代码,比如 zh,则对 atlasglob.axd 的请求将会出现错误。[请参见(链接已失效)]

还有一个另外,今天还发现了一个重要度比较低的 bug:某些预定义的日期 pattern 多了一些单引号。比如 zh-CN 中,'y' 应该解释为 yyyy年M月,而 atlasglob.axd 返回的是 yyyy'年'M'月'。比如,String.format('{0:y}', new Date(2006, 9, 1)) 返回的是 2006'年'10'月' (注意多出来的那几个单引号)。

3)AtlasCompat.js

Atlas 引入了一种手段,如果客户端是非 IE 的 Firefox/Mozilla 系或者 Safari 等浏览器时,自动加入一个脚本 AtlasCompat.js,尝试给这些浏览器的一些 prototype 加以扩展,以实现和 IE “兼容”的 API。

比如:为 Firefox/Mozilla 的元素(Element)扩充 innerText,children 等 IE 脚本中很常用的属性,还有 attachEvent 和 detachEvent 等 IE 独有的方法。

Event 的处理模型在 IE 和 Firefox 之间的差别很大。比如:获取触发事件的对象,在 IE 用 event.srcElement;在 Firefox 需要用 event.explicitOriginalTarget。event 对象的大部分属性在 IE 和 Firefox 之间都是不同的名字,功能实现上也有很多差异。另外,event 对象的获取与传递,也是件比较麻烦的事情。[请参见(链接已失效)] 

关于 Event 这里多写几点:

我们知道在脚本中为 Event 挂接函数有两种写法:

(甲) btnSave.onclick = function() { alert('hello'); }

(乙) btnSave.attachEvent('onclick', function() { alert('hello'); });

(a) 如果你希望访问 event 对象,则建议尽可能使用(乙)方式挂接事件处理函数。因为在这种情况中,你可以按照 IE 中的写法直接访问 event 对象的各个属性。

(b) 很抱歉,发布后发现了错误,重写了这一小节(b),希望没有给你带来错误认识。

我选了一个普通的 HTML Button (非 Submit 的按钮),写了如下的测试脚本:

    btn.onclick = function() {
        alert('test1');
    }
    btn.attachEvent('onclick', function() {
            alert('test2');
        });
    btn.attachEvent('onclick', function() {
            alert('test3');
        });
    btn.onclick = function() {
        alert('test4');
    }
    btn.attachEvent('onclick', function() {
            alert('test5');
        });

分别在不同浏览器中试验:在 IE 6 中依次提示:test4, test3, test5, test2。在 Firefox 1.5 中依次提示:test4, test2, test3, test5。在 Opera 9 中依次提示:test2, test3, test4, test5。

共同的特点是:test1 没有被 alert 出来,说明使用(甲)写法的代码,只有最后一个有效,前面的都会被覆盖掉。

不同的是这些“Event Handlers”执行的顺序在不同浏览器之间存在差异。IE 6 和 Firefox 会首先执行(甲)写法挂接的最后一个函数,然后执行(乙)写法的函数。而对(乙)写法的多个函数之间的顺序,Firefox 会按照挂接顺序执行,IE 6 的顺序不知道该按什么规律去解释。Opera 9 的顺序比较好解释:不区分(甲)(乙),全部按照挂接顺序执行。因此可以说,挂接的多个“Event Handlers”的执行顺序,在编码阶段是不可预知的。

再举一个场景,将上面的 HTML button 换成一个 ASP.NET Button 控件。很多时候,客户都会要求“删除”按钮上加上 confirm 确认,如果操作者选择“取消”,button 不提交表单。或许用的较多的方法,就是利用“return false;”:在 IE 中,当“Event Handler”返回值为 false 时,button 就不再提交表单。

    btn.onclick = function() {
        return confirm('Are you sure?');
    }
    btn.attachEvent('onclick', function() {
            return confirm('Are you sure?');
        });

经过试验,在 IE 6 中,这两种写法都能如你所愿。而 Firefox 1.5 和 Opera 9 中,只有前者在 return false 时不提交表单,后者即使 return false 也要提交表单。

因此,如果你希望通过“return false;”方式阻止按钮提交表单,应该使用(甲)方式。

关于 AtlasCompact.js 总的来说,为熟悉 IE 的编程人员提供一条编写跨浏览器脚本程序的捷径,但由于浏览器间的细节差异,仍然还有不少地方是需要注意的。

(本文所写内容基于 2006 July CTP 版本的 Atlas。文中所得到的结论分别基于 IE 6, Firefox 1.5 和 Opera 9。)

posted on 2006-10-11 22:10  破宝  阅读(174)  评论(0编辑  收藏  举报

导航