JavaScript DOM動態創建(聲明)Object元素


http://www.cnblogs.com/GuominQiu/archive/2011/04/01/2002783.html

一文提及“等整個頁面加載完畢后,根據用戶所選的閱讀機類型,再用JavaScript DOM動態創建(聲明)Object元素。這樣可以避免加載沒用到的控件,避免頁面加載過慢。”

文中“DOM創建、添加元素具體就不詳述了。”一句帶過的部分內容,有朋友需要。我也曾經是個菜鳥,摸索出來的,願意分享給后來者;另外,我也深知有些設備調試需要耐心和經驗。但是,我已經兩年多沒接觸代碼了,所以沒可能說的很詳細或准確;此外,基於保密,也沒法全部代碼貼出,只能說說思路。特此說明,大家有問題評論說明即可。

個人非常喜歡這種解決方案。最大的好處就是模塊化了。做這種設備相關的都知道,設備有不同廠家,即使同個廠家,型號升級也是很正常的。舊的廠家退出,新的廠家中標要提供接口測試。怎么辦呢?不同廠家接口都不同(除非,你方足夠強勢,強勢到廠家為你們的系統特別定制,那你需要文檔說明,要求提供什么接口,返回什么類型,但是。。。這個很難),新型號也要調試,廠家又天各一方,大家聯調很難,又浪費時間。這種模塊化就可以將這設備相關部分剝離開來,弄一個靜態頁面,將你系統相關的邏輯javascript放一個文件,不同廠家提供你所需的調用函數放另外一個單獨文件,這樣,你只要要求廠家按你要求提供接口即可,這樣也方便調試。當然,靜態頁面和實際的生產環境還是可能有差別,但是這已經和功能關系不大了(比如生產環境Windows登錄的帳號是權限受限,.ASPX動態頁面和靜態頁面的差別,cache等等),調試需要的就是耐心和細心。

 

后記:改完代碼后發現,雖然骨架還在,但是已經面目全非。看得懂就看吧,估計高手也不用看都知道;看不懂也就只能這樣子了。我也喜歡直接抄別人代碼,但是發現很多時候都行不通,最后次數多了只好自己好好學習原理,然后再在前人的基礎上改進完善,以達到為己所用的目的。不然出問題也說不出個所以然。

黑體加粗部分就是動態添加object聲明的。這部分也是需要特別耐心調試的。因為不同廠家,各屬性都不同,有的需要添加a屬性,有的不用,我保留了兩個典型的型號。添加事件也不同,有的廠家需要帶參數,有的不能;有的不能在此處往控件添加事件(有的事件會執行,有的不會,很奇怪,可能動態生成后頁面沒完全加載完畢,僅僅猜測而已),此時保險的做法就在頁面寫算了。此外,有的ocr空間設置display屬性,也可能導致不能得到效果。有的控件自帶調試gui界面,那可以先顯示出來,方便調試。

 

還是那句話,原理很簡單,需要的是耐心和細心。


//var m_ReaderOpened =false;//開關

//獲取設備型號名稱
function GetReaderName() {
    var resutl = "";
    switch(EF.iMachineType) {
        case "1":
            resutl = "叫什么名字的設備";
            break;
........
        default:
            resutl = "未知類型:" + EF.iMachineType;
            break;
    }
    return resutl;
}

//關閉設備釋放資源——這個最需要注意,廠家接口做的不好,沒有釋放內存的話,很容易導致IE崩潰。
function CloseReader()
{
    //if(m_ReaderOpened == false )return;
    theTop.status = "CloseReader";

    try {
        switch(EF.iMachineType) {
            case "1":
                //...
                break;
.......
            default:
                theTop.status = "未知類型:" + EF.iMachineType;
                break;
        }
    }catch(e){
        //alert("試圖關閉端口時出錯:"+e.message);
        theTop.status = "試圖關閉端口時出錯:"+e.message;
    }
}

//點擊"xxxxx"按鈕, 初始化設備, 加載ActiveX
function OpenReader()
{
    //if(m_ReaderOpened == true)return;
    theTop.status = "OpenReader";
    
    //閱讀機初始化失敗產生的可能原因
    var AdivseNote = "\n\r";
    AdivseNote += "請確認設備:\n\r";
    AdivseNote += "1.電源指示燈是否點亮(電源開關處於ON[開啟]狀態);\n\r"
    AdivseNote += "2.數據線與計算機連接完好(串口或USB);\n\r";
    AdivseNote += "3.所選設備型號["+ GetReaderName() +"]是否與實際設備一致;\n\r";
    AdivseNote += "4.當前所插入的USB端口的驅動已安裝(如果是需要安裝驅動的型號);\n\r";
    AdivseNote += "5.當前運行網客戶端是否已開通USB端口;\n\r";
    AdivseNote += "6.刷卡器端口可能已被其他窗口占用;\n\r"

    try{
        if(EF.iMachineType == "1")
            //開啟端口,初始化工作
........
    } catch(e) {
        alert("初始化設備["+ GetReaderName() +"]失敗!" + e.message + AdivseNote);
        btnCancel_Click();//初始化設備失敗, 返回點擊刷卡前的狀態
        //點擊取消按鈕無效,希望重新加載頁面可以解決刷卡過程中出現的“端口被占用”的問題。
        window.location.href = window.location.href;
        return;
    }
}

// 檢查控件是否正確安裝
function CheckExistOcr() {
    try {
    //各ActiveX的項目名稱可以通過clsid在已安裝控件包的客戶端的注冊表中查找到
        var tmpObj;
        switch(EF.iMachineType) {
            case "1"://xxxxxxxxx00
                tmpObj = new ActiveXObject("ProjectOcx.UserControlOcx");
                break;
.............
            default:
                theTop.status = "未知讀卡器類型:" + EF.iMachineType;
                break;
        }
        return true;
    } catch(e) {
        $get("lblTips").style.display = "";
        //$get("lblTips").innerText = "";//ActiveX 控件加載失敗! -- 請檢查瀏覽器的安全設置或確認是否已安裝機所需安裝包。
        $get("lblTips").innerHTML = "<span style=\"color: red\">沒有安裝機["+ GetReaderName() +"]所需控件!</span>";
        return false;
    }
}

//根據選擇機類型自動創建對象,避免頁面加載過慢, 特別是機型號不斷增加的情況下
function AutoCreateObjectBaseOnChoose() {
    var inputElement = document.getElementById("inputElement");//元素容器
    var ocxObject = document.createElement('object');//ocx控件對象
    //var s = document.createElement('script');//給控件注冊事件//temp
    //s.type = "text/javascript";//temp
    ocxObject.style.width = "0";
    ocxObject.style.height = "0";

    try {
        switch(EF.iMachineType) {
            case "1": //AAAAAAAA
                ocxObject.id = "xxxxx";
                ocxObject.name="xxxxx";
                ocxObject.classid="clsid:xxxxxxxxxxxxxxxxxxxx";
                ocxObject.codebase="xxxxx.ocx";
                ocxObject.style.display = "none";
                //s.EVENT = "ProductChange";//temp
                //ocxObject.attachEvent("ProductChange", xxxxx_ProductChange);

                //ocxObject.style.display = "none";//這句可能會導致事件無法觸發——不同設備不同
                //ocxObject.attachEvent("OnButtonEvent(nButtonFlag)", GetData);
                break;

            case "4": //BBBBBBBBBBB
                ocxObject.id = "BBBOcr";
                ocxObject.classid = "clsid:XXXXXXXXXXXXXXXXXXXXXXX";

                //這里注冊需要事件處理函數存在, 否則會導致注冊失敗. 改在頁面聲明不存在此問題——和廠家提供的ocr控件有關
                //ocxObject.attachEvent("DocumentArrive", DocumentArrive);
                //ocxObject.attachEvent("DataReady", DataReady);
                //ocxObject.attachEvent("MreError", MreError);
                break;
            default:
                theTop.status = "未知讀卡器類型:" + EF.iMachineType;
                break;
        }
        //s.FOR = ocxObject.id;//temp
        //window.document.getElementsByTagName("head")[0].appendChild(s);//temp
        //如果創建了對象, 再添加到頁面, 即使長寬設置為0, 都會造成左下角一個空白方塊
        if(ocxObject.id && ocxObject.id.length > 0) {
            inputElement.appendChild(ocxObject);
        }
    }catch(e){
        alert("動態創建ocx對象失敗:" + e.message);
        theTop.status = "動態創建ocx對象失敗:" + e.message;
    }
}

window.attachEvent("onload",  AutoCreateObjectBaseOnChoose);

//--------------------------------------------------------------------------
//以下是設備a
function DocumentArrive()
{
//到達事件響應事件
}

function DataReady()
{
//識別正確事件響應函數
}

function MreError()//識別錯誤事件
{
    alert("識別失敗, 請重刷!");
}
//--------------------------------------------------------------------------
//以下是設備B
function GetData() {
//將設備返回的數據進行處理,再顯示在頁面或使用
}
//--------------------------------------------------------------------------


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM