IE8 的 JSON 解析 BugMay 21, 2009

使用 IE8 时发现其 原生的 JSON 解析器 存在 Bug,让我们先用 IE8 打开 DEMO 页面体验下。

http://lab.gracecode.com/bug/ie8-json-stringify.html

看图购的 AIR 版本(预览版)April 18, 2009

http://lab.gracecode.com/imgo/images/logo.png

相信很多关注淘宝的朋友都知道 淘宝近期出了个「看图购」项目 。细心的朋友也会发现,看图购本身是基于 API 的,那么我们就可以根据这个 API 玩出很多花样。

最近也了解了下有关 Adobe AIR 的些东西,于是就拿它来练练手。AIR 真的很容易上手,花一天的时间了解 SDK、花一天的时间编写界面、然后花两天的时间编写脚本,于是就捣鼓出了这个小玩意。

由于 PD、PM、交互、视觉、前端几乎都是我一个人,加上时间较紧,这东西还有很多优化的余地。大家有任何的意见和建议,欢迎提出。

-- Split --

Realazy 兄已经有了针对 AIR 的很中肯的点评 ,在这里我说下我的看法:

使用原有的技术即可实现传统桌面端软件的效果,AIR 的确提供给众 Web 应用提供商开发「桌面端」软件的最低成本的一种方式。同时,AIR 本身的易用性真的让人感到惊艳,以前使用的些开发经验和技巧可以完全的保留。

很多人都看好类 AIR 这种技术会在不久的将来会风行,我还是持比较谨慎的态度。

首先,传统桌面端开发环境的成熟程度是 AIR 望尘莫及的,这犹如小毛孩子和七尺壮男打一架是不现实的。

其次,还是不得不说的架构问题。AIR 目前架构从本质上说,还只是浏览器套上了层系统的外皮 -- 它实质上还是浏览器。要求它完全实现客户端软件的功能,还是有点强人所难的。

同时,正因为此,AIR 的性能还是让人感所诟病。不解决这一问题,AIR 会难以胜任更高层的应用,只能沦为前端的调味品。

正是因为利用 AIR 如此的便利,如果发挥不当会如 cherish 所言的那样,「让大部分的 Web 开发者变成披着狼皮的羊」 。在目前相对浮躁的互联网环境下,尤其要注意这点 -- 工具本身没有错,就看怎么利用了。

最后,还有个心得是设计模式上的 -- 桌面端与传统的 Web 开发思维的确有微妙的不同,由于使用 AIR 时间并不长,就不班门弄斧了。

-- Split --

下面是「不负责任」的免责声明,有时候这是必须的。

本程序出于个人兴趣爱好制作,与淘宝网官方无关。因此程序造成的所有后果,本人与淘宝网不承担任何责任。

-- Split --

好了,说了那么多,兄弟们这就开始体验吧: http://lab.gracecode.com/imgo/ ,等到代码「可以见人了」,在适合的情况下会开源的 :^)

事件检测April 9, 2009

给浏览器绑定事件有时候是非常痛苦的事情,不同的浏览器提供不尽相同的功能的同时,也提供了不同的事件。例如,IE 系列的浏览器支持 mouseenter/mouseleave 事件;Opera 不支持 contextmenu 以及 input 相关的 onbeforepaste、onbeforecut 等事件。

浏览器之间不同程度的事件支持情况,会加重编写跨浏览器的开发成本。而在某种「无奈」的情况下(特别针对 IE),我们都会采用 浏览器嗅探 来决定绑定不同的事件,例如绑定鼠标滚轮事件:

if (Env.ua.ie) {
    Event.on(document, 'mousewheel', callback);
} else {
    Event.on(document, 'DOMMouseScroll', callback);
}

或者另外中做法就是干脆绑定两个事件。虽然这也能很正常的工作,但我们都了解,无论是基于浏览器嗅探还是重复绑定无用的事件,这都是不完美的解决方案。

Juriy Zaytsev 的代码 给了我们解决这个问题的些启示,他利用 DOM 的特性,来判断针对某元素是否支持具体事件。例如

var el = document.createElement('div');

el.setAttribute('onclick', 'return;');
typeof el.onclick; // "function"

el.setAttribute('onclick2', 'return;');
typeof el.onclick2; // "undefined"

那么,根据这一特性,就可以编写出不依赖浏览器嗅探的事件检测脚本,原文的最终例子

var isEventSupported = (function() {
    // 根据特有的事件创建对应的 HTML 元素
    var TAGNAMES = {
        'select':'input','change':'input',
        'submit':'form','reset':'form',
        'error':'img','load':'img','abort':'img'
    }

    function isEventSupported(eventName) {
        var el = document.createElement(TAGNAMES[eventName] || 'div');
        eventName = 'on' + eventName;

        // 检测元素是否已经包含了对应的事件
        var isSupported = (eventName in el);

        // 如果没有对应事件,则尝试增加对应事件,然后判断是否为回调
        if (!isSupported) {
            el.setAttribute(eventName, 'return;');
            isSupported = typeof el[eventName] == 'function';
        }
        el = null;
        return isSupported;
    }
    return isEventSupported;
})();

那么,判断是否为 Opera 浏览器使用

isEventSupported("contextmenu")

就好过

navigator.userAgent.indexOf('Opera') > -1 

而且,以后如果 Opera「修复」了该问题,由于 isEventSupported("contextmenu") 返回的是 true,从而也可保证代码健壮的运行。

最后,原文作者写了个 简单的测试页面 ,用于检测具体浏览器的 DOM Level2 的支持情况。

-- Split --

需要了解其他利用 DOM 特性的小窍门,请 查看这里

Yahoo 统计