6.简化开发

为了方便使用硕正套件，我们将原始写法做了 js 封装，封装成名为 dynaload.js 的小程序，这样开发者就不必在页面中书写上述烦人的<object ... >了。该 js 小程序封装了页面调用插件、识别浏览器类型、动态下载和创建组件实例的过程，本Demo网站中的所有演示页均调用了该 js, 它位于 binary 目录下，其源码非常简单，不到160行：

    //区分浏览器：Firefox / Chrome(34 or later) / IE(X86/X64) / 国产浏览器...
    function NewBrowserObj()
    {
     ...  //略过 (创建浏览器特征对象，探测各种浏览器以及版本、是否已安装插件等等)
    #51#}

    //浏览器对象(全局对象)
    var $B = NewBrowserObj();

    //让 ppapi 语法兼容 npapi：为 <object> 添加 func( ) 函数
    if($B.ppapi) {
     Object.prototype.func = function(funcname, para) {
      return this.postMessageAndAwaitResponse([funcname, para]);
     }
    }

    //private:
    function bldStr(ctlType, id, para, height)
    {
     var ctlver = '1.0.106.0';

     //取得组件包的绝对路径(假设和dynaload.js部署在同一个目录)
     var SupcanPath="", arrScript = document.getElementsByTagName("script");
     for(var i=0; i<arrScript.length; i++) {
      ...//略过
    #86# }

     var typeid;
     if($B.type == "ie") {
      if($B.is64)
       typeid = 'CLASSID="clsid:11249C26-4BCD-4A74-B4D9-068936D77EFE" Codebase="' +SupcanPath+ 'supcan2.x64.cab#Version=1,0,0,3"';
      else
       typeid = 'CLASSID="clsid:619F1AC0-2644-40D3-9EB1-22F81C5FE097" Codebase="' +SupcanPath+ 'supcan2.cab#Version=1,0,0,3"';
     }
     else {
      if($B.npapi) typeid = 'type="application/supcan-plugin"';
      if($B.ppapi) typeid = 'type="application/x-ppapi-supcan"';
      if($B.type == "firefox") typeid += ' Codebase="' +SupcanPath+ 'supcan.xpi"';
     }

     //拼装组件包URL
     var zipurl = SupcanPath + ($B.is64 ? "BCV1.x64.bin" : "BCV1.bin");
     if(ctlType=="LuxForm")
      zipurl += "," +SupcanPath+ ($B.is64 ? "LuxForm.x64.bin" : "LuxForm.bin");
     else if(ctlType.indexOf("BCV4")>=0)
      zipurl += "," +SupcanPath+ ($B.is64 ? "BCV4.x64.bin" : "BCV4.bin");

     //End
     var str = '<Object id=' +id+ ' Width=100% height=' +height+ ' ' +typeid+ '>';
     str += '<param Name="CtlName" Value="' +ctlType+ '">';
     str += '<param Name="CtlVersion" Value="' +ctlver+ '">';
     str += '<param Name="ZipUrl" Value="' +zipurl+ '">';
     str += '<param Name="id" Value="' +id+ '">';
     str += '<param Name="Cookie" Value="' +document.cookie+ '">';
     str += '<param Name="CtlPara" Value="' +para+ '">';
     if($B.ppapi) str += '<param Name="core" Value="pure"><param Name="Locate" value="' +window.location.href+ '">';
     str += '</Object>';
     if($B.ppapi) { //为 ppapi 添加事件侦听函数, 在其中直接调用 OnReady、OnEvent, 达到语法和 npapi 兼容的目的
      str += '\n<script>\n' + id + '.addEventListener("message", handleMessage' +id+ ', false);\n'
      str += 'function handleMessage' + id + '(message) {\n if(message.data.name=="OnReady") OnReady("' +id+ '");\n else if(message.data.name=="OnEvent") OnEvent("' +id+ '", message.data.event, message.data.p1, message.data.p2, message.data.p3, message.data.p4); \n }\n</script>';
     }
     //alert(str);
     return str;
    }

    //public:
    function insertTreeList(id, para)   { document.write( bldStr("BCV1.TreeList",   id, para, (arguments.length > 2) ? arguments[2]:"100%") )}
    function insertEdit(id, para)   { document.write( bldStr("BCV1.Edit",   id, para, (arguments.length > 2) ? arguments[2]:"100%") )}
    function insertReport(id, para)   { document.write( bldStr("LuxForm",   id, para, (arguments.length > 2) ? arguments[2]:"100%") )}
    function insertTree(id, para)   { document.write( bldStr("BCV1.Tree",   id, para, (arguments.length > 2) ? arguments[2]:"100%") )}
    function insertFreeForm(id, para) { document.write( bldStr("BCV1.FreeForm", id, para, (arguments.length > 2) ? arguments[2]:"100%") )}
    function insertChart(id, para)    { document.write( bldStr("BCV1.Chart",    id, para, (arguments.length > 2) ? arguments[2]:"100%") )}
    function insertUpload(id, para)   { document.write( bldStr("BCV1.Upload",   id, para, (arguments.length > 2) ? arguments[2]:"100%") )}
    function insertFormDesigner(id, para) { document.write( bldStr("BCV4.FormDesigner", id, para, (arguments.length > 2) ? arguments[2]:"100%") )}

    //必需的函数(控件会反向调用，用途:切换焦点)
    function focusIE(obj_or_id)
    {
      ...//略过
    #155#}

相信您一看就能明白，在页面中只要调用从 127 到 134 行之间 8 个函数的任一函数就行，这几个函数有 2 个显式参数:id、para，参数id就是<object id=...>中的id值，参数para就是名为CtlPara的<Param>的值，我们称之为“创建参数”，此外还允许有隐含参数：控件的初始高度，如果不指定这个高度，就以100%高度展现。

第 66 行中的版本号，该版本号是自动升级的关键.

其中的 focusIE( ) 是必需的，你可能永远不会去调用它，但是组件会去反向调用它的.

8个函数中，第三个参数被设成隐含参数，目的是为了版本兼容，在 1.0.82.0 本前，都只有 2 个参数.

强烈建议不要修改文件名、不要随意修改文件内容, 也不要添加内容, 因为我们每个版本发布时, 里面的版本号都会变更的.