减少js应用的侵入性

这里主要总结浏览器前端的侵入性问题,诸如nodejs那样的应用不在本文的讨论范围。

 

编写浏览器的js应用无非用到三大件:js、css、html,而这三样东西都有可能对浏览器造成侵入性,这样前端的js应用免不了会和页面中的其他相关内容起冲突,如样式乱掉、JS错误、某html标签不被支持等问题,造成侵入后,要么是自身的东西影响了其他的,要么自身的东西被影响了。当然如果全部是项目定制开发,具有一定的代码规范和命名规则,这倒是还好,相信资源冲突的可能性比较小。在这里不得不喷一下jquery-ui,经常会看到其ui被站点样式影响到,变得奇形怪状的。

 

在编写kooboo cms inline editing应用的时候,遇到了很多的侵入性问题,inline editing所运行的环境是成千上万个kooboo cms站点的前台页面,环境相当的复杂而且不可预测,你永远不知道用户会开发什么样的站点,用什么样的js、css、html,用户的js是不是有运行错误,用户的css是不是有兼容性问题,用户的html是不是有正常闭合或是嵌套错误。。。。

 

以下是总结:

 

1.html标签的使用,如果你的应用所用的标签都是div,那我想被影响的几率将会非常的大,其实可以使用一些不常见的标签比如<var></var>等等,或完全可以使用自己定义的标签来如<rulee></rulee>,在inline editing中使用了var标签,虽然比起div,冲突的可能性已经比较小了,至少以目前的实际使用情况来讲是这样的,不过因为这是一个w3c中有定义的标签,心里总是觉得不那么放心,找个机会还是要换掉var的,要是早点一研究出使用自定义标签的方法就好了。

------对的,自定义标签其实不是可以自己随便定义的,我实验的结果是:除IE6、IE7、IE8外所有浏览器都可以自定义标签,也就是能正常解析<rulee></rulee>,相互嵌套也正常,显示为inline样式。IE6、IE7、IE8不能正常解析和显示,用Devtoolbar查看显示为嵌套不正常,出现各种问题。。。直到在同事推介用一个js组件的时候这个问题才解开,这个组件就是http://code.google.com/p/html5shiv/,它的作用就是让旧版本的IE浏览器认识html5的新标签类型,它的代码非常的简单,其中最重要的一句代码就是document.createElement('rulee'),执行这样一句代码后旧版本的浏览器就认识了rulee标签,显示正常为inline样式,嵌套没问题,哦也!

<rulee class="main">
    <rulee class="title">I'm rulee.</rulee>
</rulee>

 

 

2.css样式的使用,有了自定义的标签后如果样式没有使用好,冲突依然到处存在,因为你想如果js应用这样使用<rulee class="title">a</rulee>,这样的样式名.title那是多么的常见啊,不被影响到才怪呢,所以开发通用组件的时候,推介的命名方式是加上标签名限定rulee.title或外加上一个名称前缀.rulee-title也还行,这样就大大降低了冲突的可能性了。 

rulee.main{
    float:left;
}
rulee.title {
    color:red;
}

 

 

3.js相互的污染,熟悉js的朋友都知道js的特性,它的动态语言特性,几乎一切都是可以自由替换和扩展,造成的问题是js应用和页面其他js非常容易相互侵入和污染,莫名其妙的问题接踵而来,所以脚本的使用也要很小心,闭包是必须的,养成一个良好的js代码习惯,用闭包隔离组件的js和外部js,同时避免污染window域,非到不得已不轻易挂接对象到window上,因为永远都不会知道会不会有另外的一个js也使用了同一个key在window上挂接对象、造成冲突。当组件依赖第三方工具时,如jquery,它会在window上挂接jQuery和$两个key。这样很可能会和用户自己引入的jquery对象造成冲突(也就是一个页面上出现多个jquery引用),jquery的开发着有考虑到了这样的一个可能性,并提供了一个解决这个问题的API:jQuery.noConflict。其它第三方工具可以参考jquery的这个API去解决相互污染的问题。

(function($){
    var context = {};
// your code })(jQuery);
(function($){
    // your code
    $.noConflict(true); // this api called at the end of your component.
})(jQuery);

 

 

4.神器iframe,这是一个创建了独立运行空间的html标签,说它是一个html标签好像太小看它的功能了,其创建了一个新的页面运行环境,内部完全不受父页面内容的影响,那是不是把组件的内容render到iframe中就完美了?当然不是,这个要看应用场合,首先iframe在显示时创建了一个新的运行域,代价比较大,会影响到页面的性能,另外通过脚本来控制也是相对比较麻烦的。目前大部分广告管理系统会青睐使用iframe来输出内容来避免侵入性,包括我自己做的广告管理系统也是使用了iframe作为输出载体,不过其实如果用好了以上的1,2,3点,完全可以抛弃iframe的。

<iframe src="about:blank;"></iframe>
var win = iframe.contentWindow;
var doc = win.document;
doc.open('text/html');
doc.write('html content');
doc.close();

 

 

容易产生侵入性的地方,一般是在目标运行环境不确定的情况,所以一般普通的项目不会太注重这个,但是强烈建议做通用组件的朋友们应该多减少侵入性的发生,这样才会是一个健壮的组件,希望这个对大家有用。

 

 

 

posted on 2012-06-29 16:18  rulee  阅读(2956)  评论(2编辑  收藏  举报