1. 程式人生 > >SUI Mobile中解決分頁js和css的一種思路

SUI Mobile中解決分頁js和css的一種思路

初次接觸MSUI,對其ajax重新整理頁面的效果很滿意。但是在團隊開發中,卻發現在使用路由時,卻發現框架並不引入路由頁面的css,更不執行頁面上的js。檢視官方文件:
MSUI官方文件,路由頁面JS安全問題

切換到的新頁面中的 js 不執行

由於瀏覽器安全性考慮的限制以及可能的 js 重複執行或覆蓋的問題,目前是不支援執行 ajax 載入的頁面裡面的 js 的,參考 #120。

解決方法:所有頁面都引用相同的 js,而這個 js 裡面包含了所有的邏輯,事件部分使用委託來繫結。

這是真的是一個梗,而大概看了sm.js文件後,發現在載入路由頁面時,sui就只將目標頁面的class為page-group的div內容替換調當前的頁面的div,而把其頁面的js和css都給忽略了。那麼既然知道這個問題的來源,我的思路就自然是從原始碼中將js和css取出來,在進入頁面時載入,在下個頁面是銷燬。

於是,我在msui的第一個頁面加入瞭如下程式碼:

function sui_ajax_callBack(html){
       window.sui_ajax_data = html;
   }

   $(document).on("pageInit", function(e, pageId, $page) {
      //銷燬之前的私有style
      $(".page_style").remove();
      //銷燬之前的私有js物件
      if(typeof(pageJS) !== "undefined"){
        pageJS = null;
      }

      var
ajData = null; //設定html頁面資料快取 if(!window.htmlCache){ window.htmlCache = {}; } //將頁面資料放到頁面快取 if(!window.htmlCache[pageId]){ var ajData = window.sui_ajax_data; window.htmlCache[pageId] = ajData; //銷燬sui_ajax_data window.sui_ajax_data = null
; }else{ ajData = window.htmlCache[pageId]; } if(ajData){ var $doc = $('<html></html>'); $doc.append(ajData); //新增私有syle,這樣的頁面渲染是否有問題,待考察 var $style = $doc.find(".page_style"); //私有style物件 $("html").append($style); //執行私有js var script = $doc.find(".page_script").html(); eval(script); pageJS_init(); //呼叫頁面私有js } });

而在sm.js的_loadDocument 函式裡面呼叫sui_ajax_callBack函式:

 Router.prototype._loadDocument = function(url, callback) {
        if (this.xhr && this.xhr.readyState < 4) {
            this.xhr.onreadystatechange = function() {
            };
            this.xhr.abort();
            this.dispatch(EVENTS.pageLoadCancel);
        }

        this.dispatch(EVENTS.pageLoadStart);

        callback = callback || {};
        var self = this;

        this.xhr = $.ajax({
            url: url,
            success: $.proxy(function(data, status, xhr) {
                // 給包一層 <html/>,從而可以拿到完整的結構
                var $doc = $('<html></html>');
                $doc.append(data);  

                //加入自定義回撥函式
                if(typeof(sui_ajax_callBack)==="function"){
                    sui_ajax_callBack(data);
                }

                callback.success && callback.success.call(null, $doc, status, xhr);
            }, this),
            error: function(xhr, status, err) {
                callback.error && callback.error.call(null, xhr, status, err);
                self.dispatch(EVENTS.pageLoadError);
            },
            complete: function(xhr, status) {
                callback.complete && callback.complete.call(null, xhr, status);
                self.dispatch(EVENTS.pageLoadComplete);
            }
        });
    };

好了,主頁js寫好了,那麼路由頁面的js和css怎麼寫呢,看如下程式碼例程:

這裡寫圖片描述

OK,基本問題解決了,但是這只是提供一種思路,歡迎大家來提供其他思路參考。但是寫單頁前端應用,相對於傳統前端應用來說,思維習慣還真不一樣,而且開發時還需要注意記憶體的釋放(這是傳統前端應用開發時不用管的東西)。