SUI Mobile中解決分頁js和css的一種思路
阿新 • • 發佈:2019-02-20
初次接觸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,基本問題解決了,但是這只是提供一種思路,歡迎大家來提供其他思路參考。但是寫單頁前端應用,相對於傳統前端應用來說,思維習慣還真不一樣,而且開發時還需要注意記憶體的釋放(這是傳統前端應用開發時不用管的東西)。