概要
本文通过意在和大家分享一个运营了15年的老旧站点,升级为流行的Bootstrap风格的解决方案。来说明如何让bootstrap运行在各种版本的jQuery环境中。
旧站点现状
当前站点为运行在IIS 下的ASP.NET站点,重要页面50个,常用页面300个,总共约1000个页面。这些页面服务于销售部的2000多名销售人员。该站点历经15年大大小小无数项目的建设。
-
前端JS插件: 插件情况极其复杂,有来自jQuery-ui库的标准插件,有来自第三方的插件,有的插件第三方已经不再维护,有基于jQuery-ui标注库作了定制开发的插件,有些插件对jQuery版本有硬性要求,必须是某一个特定版本。
-
前端jQuery库:母版页jQuery为1.5.2版本,很多页面基于不同的项目和供应商引入了其它版本的jQuery,基本从1.5.2到2.0.0的版本都可以找到。
升级目标
主要目标为将页面布局升级为现在流行的响应式布局,引入项MegaMenu这样流行的Bootstrap组件,对于已有的功能,不做任何调整,修旧如旧。具体如下:
1.升级原有站点的母版页(5个) ,将原有的左右结构布局,调整为当下流行的响应式布局如下:
3. 页头插入Bootstrap的MegaMenu
4. 侧栏导入插入原有左右结构内容的左侧导航,并应用Bootstrap插件
5. 主体内容内容为原有左右结构内容的右侧主体页面内容
升级关键路径
Bootstrap硬性要求jQuery的版本必须是高于1.9.1的,而当前站点jQuery版本混乱,有来自母版页的,有来自具体页面的。每个页面逐一升级处理时间上不允许,甲方也找不到熟悉所有页面功能的业务人员去进行测试。
解决方案
基本思路
基于现状,如果我们可以做到让新引入的Bootstrap和jQuery 2.0的代码完全隔离在母版页中,仅在母版页中生效,即保证Bootstrap的MegaMenu和SideBar正常运行,不对具体的内容页面产生任何影响,则升级最大的问题也就解决了。
jQuery和Bootstrap代码分析
jQuery无论任何版本,执行完,会生成一个在window下的对象jQuery,该对象也会同时赋值给$。
执行bootstrap.js代码有一个要求,必须要先把Boostrap的JavaScript插件的html写好,如Tabs,MegaMenu等,然后运行bootstrap.js,会将写好的html上绑定具体的事件。这样运行后,像Tabs,MegaMenu等组件,就可以正常工作。
方案总结
我们先把需要的MegaMenu和SideBar的html准备好,然后在一个隔离的环境中运行jQuery-2.0和bootstrap.js,则可以实现我们期望的效果,即Bootstrap插件在母版页正常运行,其他页面内容不受任何干扰。
现在的唯一问题就是隔离,我像很多人也想到了,JS里面最好的隔离方式就是闭包。我们以闭包的方式将jQuery-2.0, bootstrap.js, MegaMenu和SideBar初始化的代码封装到其中,一旦通过闭包进行封装,我们完全不用再担心运行的JS代码产生的局部变量。
我们可以对bootstrap.js稍加改动,让其不在依赖名为jQuery的对象,而是我们自己定义好和jQuery功能完全一样却名称不同的局部对象,例如jQueryBootstrap。这样就不会影响闭包之外的其它jQuery对象。
对于已有的旧页面,由于通过闭包引入jQuery,可以完全忽略jQuery在闭包中的执行过程。因此,旧页面的前端代码不会受到任何影响。
对于未来开发完全基于Bootstrap的新页面,其他供应商的开发团队可以忽略母版页的内容,在自己的页面引入其他高版本的jQuery和Bootstrap,由于我们的bootstrap.js代码是放到闭包中运行的,因此,完全不会影响其他页面再引入的bootstrap.js。
方案实施
- 创建一个bootstrap-jquery.js文件。该文件只包含一个自执行函数。
(function(){
})()
- 将官网下载的bootstrap.min.js文件内容拷贝到自执行函数中。
- 将拷贝代码中的jQuery替换为jQueryBootstrap,请注意截图标红部分不要替换。
- 在Bootstrap版本信息之上,添加jQuery处理版本冲突和定义jQueryBootstrap的代码
- 添加jQuery2.0的代码,并放置到到第4步代码之前。
- 在自执行函数最后添加 MegaMenu和SideBar初始化代码。
最终,在母版页中,保留原有的jQuery 1.5.2文件的引用,增加bootstrap-jquery.js文件的应用。
浏览器在加载升级后的页面时候,只有加载模板页时候,才会执行bootstrap-jquery.js中的自执行函数。函数运行完成后,再加载内容页面,内容页面中再引入任何jQuery或Bootstrap,均不会收到影响。
Demo说明
为了更好的说明该解决方案,我特地制作了一个demo:
- demo中leagacy.html页面,让bootstrap的Tabs和jQuery 1.5.2的Tabs同时运行在一个页面中,以模拟旧页面的情况。
- demo中new.html页面除了引入bootstrap-jquery.js,还引入了bootstrap.min.js和jQuery2.0,以模拟新页面的开发。