ieBetter.js-让IE6-IE8拥有IE9+,Chrome等浏览器特性

一、发展与变化,疑问到实践

我之前就多次提过(例如介绍HTML5 API classList的时候)这样的疑问:“现代浏览器的API相当丰富与强大,几乎可以很轻松应付各类交互,为何还要引入庞大的JS框架?”

事物总是在不断发展的,人的认知也要随着事物的发展不断变化。

在北京奥运会如火如荼举行的那会儿,jQuery等一些JS框架犹如农场的鸡毛满天飞,争论孰好孰坏优缺点的口水喷得鸡毛飞得更高。

大家现在静下心来想一想,为什么那个时候,JS框架这么的炙手可热,争相关注?

在那个点,Chrome浏览器还没有正式出生(2008-09-02),还没有现代浏览器的概念,高档点的浏览器也就是FireFox以及出众但没受众的Opera浏览器。在China, 还是IE6一统天下,IE8 3月底才发布。

从目前的眼光看,那时候的浏览器世界是不是弱爆了哈!兼容性差异是不是强爆了啊!那是时候,我厂甚至只关心IE浏览器的兼容,FireFox就像农场的鸡屎,走路时候都是避开的。

此时,解决了兼容性问题,很多优秀方便API的JS框架自然成了香饽饽。这种感觉就像是,没吃没穿的旧时代里看到自行车的那种感觉,酷啊!

但是,现在呢?

变了,诸位。世界已经大便,错了,是大变!已经不是你骑个大杠自行车就嚣张的时代了。
大杠自行车

我们来审时度势下现在的浏览器世界:
近3个月浏览器市场份额

以上为百度浏览器研究院提供的最近3个月的浏览器份额。

可以看到,IE6-IE8浏览器加起来已经不足50%. IE9+, Chrome等其他现代浏览器已经占据了大半的江山。要知道,这大部分的浏览器有着丰富且兼容统一的API,可以很好的支持日常的一些或数据的或DOM的操作功能。

也就是说,浏览器世界现在分为了两个阵营:IE6-IE8保守派IE9+, Chrome等现代派

对于现代派浏览器而言,实际上类似jQuery这样的框架已经没有多少真正的价值可言!现代浏览器在选择器、事件处理、数据处理等方面都很高大上。除了API名称长了一点,我是看不到什么明显不足的!

要知道:这个世界,绝大多数的网站都不复杂!

我敢打包票,很多人在自己的页面上引入jQuery, 可能就是仅仅用下其中的选择器API,方便选择一些元素,如获取className包含.ieYouCanntSelectMe的元素!

我说亲哪,占了大半江山的现代浏览器自己有超级强大的选择器API的,你为何为了老不死的IE6-IE8让我们也去加载庞大啰嗦的jQuery文件啊!

看到没,诸位,看到没,都21世纪了,还有“株连”这样匪夷所思的事情发生,难道你都没有一点感觉吗!!?

现代浏览器不断发展,却还跟10年前一页,要依赖庞大的框架,那浏览器规范、发展的的价值又在什么地方呢?

从实际工作讲,类似的情形还有很多。

作为技术分享者,必定要经常写demo. 由于选择器API以及事件兼容性,同时要兼顾页面不要太笨重,我是使用自己写的zxx.js库。虽然小,但还是有问题,现代浏览器还是要额外加载JS文件,还是要请求,空间流量还是被消耗。显然,我需要更适合的东西。

我们都会参与一些周期较短的小项目。可能总共就几百行的JS代码。结果,超过97%的流量被用在了加载mini压缩后还80-90K的jQuery框架上。现代浏览器活脱脱躺着也中枪啊!

因此,我觉得理想的情况应该是这样的
撇开类似网盘这种富交互的项目,大多数的页面,淘宝页面这种程度的,现代浏览器不加载任何的JS框架,jQuery, Kissy通通扔到别人碗里去,至于IE6-IE8浏览器,按照现代浏览器的API来工作就好了!也就是,你只要关心在现代浏览器下如何使用,至于IE6-IE8,额外引入一个补丁JS,万事OK,歌舞升平,天下大吉!

这个引入的补丁JS就是这里的ieBetter.js. 我将这种引入称之为JS的“趋同策略”。

换种更通俗的描述就是:
以前——用苹果手机的和用塞班手机的为了兼容统一,全部使用重新包装的红旗手机;
现在——塞班手机单独自己外面套层壳子,伪装成苹果手机,而这个壳子就是ieBetter.js.

不知不觉中,我之前的疑问现在已经成了真实的实践!

这里,推荐下hax在几年之前具有远见的文章:“关于国内前端和JS技术发展的乱想”。我看后有启发,我会在文章中补充点内容。

二、Github项目、使用以及API文档

Github项目
该项目已放在Github上,地址是:https://github.com/zhangxinxu/ieBetter.js

在我写这篇文章的时候,ieBetter.js还是v1.0.0测试版本,其中必定有诸多可以完善的地方。欢迎一同建设!

//zxx: 项目名称应该是ieBetter.js结果没注意,.js没加,有谁知道如何修改项目名称吗?

目前,ieBetter.js压缩后大小30K. 大小基本上是jQuery的1/3.

如何使用
IE9+以及Chrome, FireFox等浏览器直接出门左转欣赏浪漫的雾霾景色。IE6-IE8浏览器引入ieBetter.js. 如何无干扰引入?

第一个想到的是IE的条件注释,如下:

<!--[if lte IE 8]>
<script src="ieBetter.js"></script>
<![endif]-->

但是,IE10+浏览器已经跟条件注释say googbye了!因此,例如我的IE11浏览器的IE7, IE8兼容模式下,条件注释直接被吊死,没气了!

于是,为了更广泛的适用性,可以试试下面这个方法:

if (!document.addEventListener) {
    // IE6~IE8
    document.write('<script src="ieBetter.js"><\/script>');	
}

或者您有什么更好的只让IE6~IE8加载ieBetter.js的方法?

API文档
目前,ieBetter.js跟现代浏览器套近乎的API有:
• 选择器相关API
*.querySelector
*.querySelectorAll
*.getElementsByClassName

• 事件相关API
*.addEventListener
*.removeEventListener
*.dispatchEvent
document.createEvent
init[|Mouse|UI]Event
input
window.onhashchange

• DOM特性相关API
window.getComputedStyle

• ES5 JSON扩展
JSON.parse
JSON.stringify

• ES5 Object扩展
Object.create
Object.keys

• Date对象
Date.now

• ES5 Function扩展
Function.bind

• ES5 String扩展
String.trim

• ES5 数组方法扩展
Array.isArray
Array.forEach
Array.map
Array.filter
Array.some
Array.every
Array.indexOf
Array.lastIndexOf
Array.reduce
Array.reduceRight

个中使用可参见我专门制作的API文档页面:ieBetter.js中文API文档页面

ieBetter.js API中文文档页面截图

欢迎反馈API文档页面的打开速度。分”慢”, “还行”, “快”三档。如果大家都反映速度不给力,我就要在自己的空间里也放一份。

由于IE9浏览器不支持classList API, 我斟酌再三,没有对其支持。

补充说明:
虽然文档中有提到,这里还要再说下。ieBetter.js的选择器API和最后的些数组方法是可以联合使用的,是个整体。

例如,遍历:

[].slice.call(document.querySelectorAll("div")).forEach(function(divNode) {
    // 折腾divNode吧~
});

其他数组方法也是类似的。

是不是还挺有潜力的哈~~

三、ieBetter.js – 与JS的内心世界亲密接触

如果要给ieBetter.js做广告的话,广告词我都已经想好了。就是“ieBetter.js – 与JS的内心世界亲密接触”。

我不清楚大家有没有这样的感觉,使用浏览器原生的API完成一些应用的时候,有一种直击心灵的感觉,有一种面对面对话的感觉,真实的,没有伪装的,与JS内心世界的亲密接触。

美好的感觉是会产生依赖的。虽然每天拿着望远镜偷窥女神的吃饭洗澡睡觉觉也是一种享受,但是,我想,直接跟女神一起吃饭洗澡睡觉觉应该更有一番滋味。难道你不这么认为吗?

虽然你可能没有多少与女神相处的经验,可能开始的时候你会碰壁,会经常犯错。但是,久了,纠正了,学习了,习惯了,你就强大了。因为,你连女神都能应付自如了,其他那些庸脂俗粉岂不根本就不在话下。

可见,ieBetter.js也是把妹技能提升了一条快速路径啊,众未来的“(const)富帅”们,还不赶快使用ieBetter.js,来和女神进行心灵交织,肉体碰撞的接触吧!还等什么呢!

压轴镇楼图

其他点什么
我个人觉得这个项目的价值和意义是蛮大的,所以非常欢迎大家fork,一同维护与建设。如果star足够多,项目趋于稳定,我会试着贡献到staticfile.org上,直接CDN访问。

我也知道,肯定也有其他同行和我有类似的想法(但我没有找到),欢迎共享你的一些心得。

欢迎交流。

原创文章,转载请注明来自张鑫旭-鑫空间-鑫生活[http://www.zhangxinxu.com]
本文地址:http://www.zhangxinxu.com/wordpress/?p=3835

(本篇完)

分享到:

标签: , , , , ,

赞助商推荐(我也要赞助)

想学到点真东西? ×
如果你有1~3年前端开发经验,不妨 ×
想找个师兄入门前端?不妨 ×
想快速入门前端? ×


发表评论(目前70 条评论)

  1. AntonKho说道:

    楼主数组的方法大多都有小BUG。
    例如
    var a = [‘aa’, ‘bb’, ‘cc’];
    delete a[0];
    ES5数组的遍历里a[0]是不会遍历出来的。
    而你的some跟every里面没过滤掉这个。
    forEach里却用for in过滤不太严谨。
    万一有人给Array.prototype[0] = ‘my text';
    就算delete a[0] for in照样是true;
    应该使用hasOwnProperty判断;

  2. 移动端使用问题说道:

    我在移动端使用了,测试出在小米的微信里,购物车飞行的过程中不连贯,会有一段路程购物车看起来像被遮挡了

  3. yoyo837说道:

    不知道这里说的和shim/polyfill概念是不是一回事…

  4. 感恩的❤说道:

    IE8下调试发现global.removeHandler方法有一个Bug,有人在GitHub上提出,可以看看Issues的讨论情况,谢谢!

  5. sdricky说道:

    请问,是不是录入你这个JS后,我就不能使用EASYUI 这类控件

  6. 小虫说道:

    效率这么重要的东西怎么只字不提

  7. holala说道:

    在ie8下直接报错啊
    if (!document.body.addEventListener) {
    这个测过吗?

  8. Zz说道:

    !-[1,]判断ie9以前啊

  9. 戈志刚说道:

    ieBetter.js放到ie8上运行会报错,第一行
    if (!document.body.addEventListener) {
    [window, document].forEach(function(global) {
    global.addEventListener = function(eventType, funcHandle, useCapture) {
    oDomExtend.addEventListener.call(global, eventType, funcHandle, useCapture);
    };
    global.dispatchEvent = function(event) {
    oDomExtend.dispatchEvent.call(global, event);
    };
    global.removeEventListener = function() {
    oDomExtend.removeEventListener.call(global, eventType, funcHandle, useCapture);
    };
    });
    }

  10. hjzheng说道:

    Good idea!!! 但是我认为还是应该加速淘汰IE6-IE8,现在XP已经不支持了,加上360等的努力(偷换内核),相信以后会越来越好!

  11. 陈烁斌说道:

    鑫旭师兄把placeholder也给加上吧。要解决input type=password这个bug哦。

    • 张 鑫旭说道:

      @陈烁斌 placeholder为IE10+支持属性,这里怕是暂时支持不了。

      • 光腚说道:

        求救个事阿,鑫工,字体图标如Font Awesome 在IE8下不能正常显示,研发给我的结果是解决不了。要换成图片。请问一下,是否有这种字体图标在IE8下的不能正常显示的处理方法或者有相关资源阿,谢谢了。IE8下图标占位,但是需要点一下,或者鼠标滑一下才可以显示,而在国外买回来看原DEMO,没有任何问题。

        • 张 鑫旭说道:

          @光腚 这个与字体没关系。IE8有个著名的inline-block渲染bug. 类似这样的问题,触发重绘就可以了。可参考:利用重绘解决IE下JS交互产生的定位重叠等棘手bug 一文。祝你好运!

        • 动次大次说道:

          呵呵,前段时间也确实遇见这个问题,用font awesome这个字体图标,在谷歌浏览器、火狐什么的都没问题,但在IE8-下就显示不出来,(PS:.NET开发的,如果IE访问用vs自带的服务器运行的项目,图标是可以显示的,但是项目发布到IIS后,用IE8访问图标就死活不出来)。后来还是用图片做图标解决的;两张图片:glyphicons-halflings.png、glyphicons-halflings-white.png 常用的图标这图片上都有。

  12. lcc说道:

    却还跟10年前一页 是不是 却还跟10年前一样?

  13. canvasT说道:

    我想说的是浏览器在发展,宽带也在发展,90K的大小,对于现在的上网条件来说,耗时应该可以忽略的吧?

    • King Deng说道:

      赞同,况且也可以使用CDN,大公司提供的CDN速度很快,也不浪费自己服务器的带宽,只要不被墙,CDN其实很好。

  14. 圣经说道:

    分析的不错!这个项目有意思!

  15. G-lin说道:

    能介绍一些前端大牛的博客吗?

  16. zyg说道:

    支持 期待发布正式版

  17. DR.SMALLKE说道:

    写得好不错,保险公司的程序员表示兼容IE6快要我老命了….

  18. 春和水水子说道:

    要向你好好学习学习,感谢分享~~

  19. leihaipeng说道:

    我经常做项目的时候会碰到.value.replace(/\D/,”)这样的实时更新value值的操作,当我用onpropertychange去捕获右击输入的内容时,这里就会造成死循环(用户右击输入时正好改变了value触发了propertychange事件,然后我又用replace去替换又变换了值,再一次触发,这里每一次更改值都会触发,因此造成了死循环),ieBetter.js避免了这个问题吗???

  20. shareFeng说道:

    动画怎么办?

  21. xiaoMo说道:

    input那里 能问下是怎么兼容的吗?大概思路,或者核心代码是什么呢?

  22. halfcoder说道:

    github项目里的代码好乱……建议发布版本使用release,项目页面使用github page

  23. Jony Zhang说道:

    建议看看 Dean Edwards 的项目:https://code.google.com/p/ie7-js/,不依赖Sizzle,36kb.
    里面包含IE7.js、IE8.js、IE9.js分别实现对低版本IE的提升,你这里的情况也就是类似于IE8.js,只不过你这里是针对js,而IE8.js针对HTML和CSS的不兼容做了

  24. 123说道:

    唉,看代码有点失望

  25. flyboy说道:

    关于 只让 ie6,7,8 加载 ieBetter.js 楼主陷入了误区。ie10开始是 不支持ie注释的。
    所以

    即可。ie10开始会直接过滤跳过这段。

  26. aaa说道:

    sizzle+es5+事件绑定兼容=isBetter

  27. tgreen129说道:

    谢谢整理

  28. hax说道:

    怕没话题聊!就说说isBetter.js好了。其实有许多可说的。你知道我很早就用这种方式。但是我也没做一个project来搞,懒当然是一个因素,但是一定有更多的问题。我们就聊聊这些问题好了。

    先举个例子,模块化。目前isBetter.js就是一坨,完全没有模块。那问题是,是否需要模块化?如何模块化?

    参考最近挖的坟:https://github.com/lifesinger/lifesinger.github.com/issues/106#issuecomment-30743757

    • 张 鑫旭说道:

      @hax 你的疑问我也想过。是否可以把Sizzle这个模块独立出?一番思考,觉得没有必要。isBetter.js的目的就是为了简单快捷的时候。且文章也多次提到,isBetter.js面向的是简单页面,中小项目;试想下你写个demo页面也要一堆细分的模块吗?再者,isBetter.js本身就是个方法流,对于页面,项目没有依赖的。硬是去跟“模块”套近乎反而是吃力不讨好的吧。工程化的项目具有强烈的工科思维自然是好。但是,并不是所有的项目都是建大桥建地铁,需要细分模块,继承以实现很好的把控。修个花坛,搭个小屋之类从哲学的角度,带着情感化的思维去实现,我觉得会更优美。这不正是大多中国的工程师所缺乏的吗?

  29. luisayu说道:

    顶一个!!!!受益匪浅

  30. 杰闻说道:

    或者您有什么更好的只让IE6~IE8加载ieBetter.js的方法?

    其实可以继续使用条件注释,IE 10 的解决方式可以在html 添加

    这么已经话,让IE10不使用兼容模式

  31. wxz说道:

    搜一下IE9.js吧,貌似和您这个目的差不多。另外如何让IE6-IE8支持canvas绘图也有库

  32. tcdona说道:

    html4shi[v/m]和这个区别在哪里

  33. hax说道:

    这种方式我从07年就开始用,10年拥抱html5大会上我的演讲主题就是这种方式。11年的时候我写了一个未来发展的想法,也提到这种方式的趋势。http://hax.iteye.com/blog/1128269

    然而到目前为止,这样的尝试虽有,但是尚未有非常流行并大量用于产品级的。所以仍然有巨大的发展空间。

    BTW,有兴趣的话到我这里玩玩,我们聊聊。

    • 张 鑫旭说道:

      @hax 哈哈,盛情之下,自然难拒!可是好不安,聊些什么东西呢,怎么聊?没体验过哈,我不善表达,到时候会不会冷场啊?……什么时候有活动了,我过去看看。对了,BTW是什么意思,“别踢我?”

  34. 巴里切罗说道:

    这个必须关注下……API速度还挺快的
    不过hashchange的那个示例需要改改呀
    每点一个菜单的链接,那里也会加上一条“颜色从继承色变成继承色;”

  35. 于江水说道:

    github 右侧 settings 可以修改,不过修改之后,url 就变了。要改的话,尽早改,不然传播出去了,就 404 了。

  36. TQ说道:

    是个很不错的想法,加油完善!

  37. 岑锦超说道:

    的确,在现代浏览器中,ie9+ 的现代浏览器都很好的支持了DOM2 DOM3 标准,和一些html5标准.es5也有很多不错的方法~这个ieBetter.js 简直太帅了.

  38. 华晨说道:

    github 右侧导航最下面有一个 Settings,进去后第一项就是修改项目名称。

  39. Jet说道:

    关键是CSS啊

  40. 吕大豹说道:

    鑫哥大作,必是精品,先顶一个~