SPA初試-1

本篇內容是在上一次的基礎上進行改進,對狀態的定義進行了修改,一個狀態的定義以下:javascript

function state(stateName, template, templateUrl) {
  this.stateName = stateName;
  if (template) {
    this.template = template;
  }
  if (templateUrl) {
    this.templateUrl = templateUrl;
  }
}

即每個頁面對應着一個狀態,一個狀態有一個狀態名,還有一個模板/模板url,這樣咱們就能夠將不一樣頁面的內容寫到不一樣的html裏,而後經過templateUrl將他們動態加載進來渲染頁面。css

先貼上js代碼:html

var states = [];
var currentState;
$(document).ready(function() {
  registState();
  console.log(states);
  currentState = init();
  //監聽hash路由變化
  window.addEventListener("hashchange", hashChange)
})

//哈希路由處理事件
function hashChange() {
  var nextState;
  console.log(window.location.hash);
  //判斷地址是否爲空,若爲空,則默認到main-view頁面
  if (window.location.hash == "") {
    nextState = "mainView";
  } else {
    //若不爲空,則獲取hash路由信息,獲得下一個狀態
    nextState = window.location.hash.substring(1);
  }
  //判斷當前狀態是否註冊過(是有存在這個狀態)0g
  var validState = checkState(states, nextState);
  //若不存在,則返回當前狀態
  if (!validState) {
    createState(nextState, "", "./test.html");
    currentState = nextState;
    return;
  }
  $('#' + currentState).remove();
  if (!nextState.view) {
    states.forEach( function(element, index) {
      if (element.stateName == nextState) {
        createView(element);
      }
    });
  }
  currentState = nextState;
}

//狀態註冊
function registState() {

  var newState = new state("mainView", "", "./main-view.html");
  var newState1 = new state("listView", "", "./list-view.html");
  var newState2 = new state("detailView", "", "./detail-view.html");

  states.push(newState);
  states.push(newState1);
  states.push(newState2);
}

//初始化,對用戶一開始輸入的url進行處理
function init() {
  nextState = window.location.hash.substring(1);
  //若用戶輸入的hash值爲空,則默認跳轉到states[0]的頁面
  if (nextState == "") {
    createView(states[0]);
    return states[0].stateName;
  }
  states.forEach( function(element, index) {
      if (element.stateName == nextState) {
        createView(element);
      }
    });
  return nextState;
}

//判斷狀態是否存在
function checkState(states, nextState) {
  var tof = false;
  states.forEach(function(element) {
      if (element.stateName == nextState) {
        tof = true;
      }
    })
  return tof;
}

//建立一個狀態
function createState(stateName, template, templateUrl) {
  var newState = new state(stateName, template, templateUrl);
  createView(newState);
  $("#" + newState.stateName).css("display", "block");
  $('#'+ currentState).css("display", "none");
  currentState = newState;
  states.push(newState);
}

//建立狀態所對應的視圖,並將視圖放到body裏
function createView(state) {
  if (state.template) {
    template = state.template;
    state.view = $("<div id='" + state.stateName + "'></div>").html(template);
    $("body").append(state.view);
  }  else if (state.templateUrl) {
    htmlobj = $.ajax({url: state.templateUrl, async: false});
    template = htmlobj.responseText;
    state.view = $("<div id='" + state.stateName + "'></div>").html(template);
    $("body").append(state.view);
  }
}

//狀態對象
function state(stateName, template, templateUrl) {
  this.stateName = stateName;
  if (template) {
    this.template = template;
  }
  if (templateUrl) {
    this.templateUrl = templateUrl;
  }
}

處理邏輯

  1. 一開始進入頁面的時候,先利用registState()註冊一些狀態,而後利用init()函數來對用戶一開始輸入的url進行處理
  2. 當用戶輸入的路由發送變化的時候,調用hashChange()函數:
    1. 獲取用戶輸入的hash值,這個hash值即爲狀態名
    2. 檢查這個狀態是否已經註冊,若已經註冊過,則將當前的頁面內容清除掉,而後爲輸入的狀態建立視圖
    3. 若狀態未註冊,則建立一個新的默認狀態

文件結構以下:

index.html裏的內容

裏面沒有任何東西,內容都是咱們動態加載進去的java

<!DOCTYPE html>
<html>
  <head>
    <title>SPA</title>
    <link rel="stylesheet" type="text/css" href="index.css" />
    <script type="text/javascript" src="jquery-3.1.1.min.js"></script>
    <script type="text/javascript" src="spa.js"></script>
  </head>
  <body>
  </body>
</html>

注意

我使用的是chrome瀏覽器,因爲安全問題,chrome必須經過http等方式才能用$.ajax來獲取到文件內容,所以我用了nodejs的http-server本身搭建了一個簡單的服務器.
其餘的頁面都只是單純的html文件,沒有什麼特別,因此就不列舉出來了node

截圖

輸入服務器的url

修改url,在後面加上#listView(以前在初始化的時候就已經註冊過的狀態)

輸入一個沒有註冊過的狀態(註冊了一個默認的狀態)
jquery

接下來打算作一下嵌套狀態,若是有什麼好的建議,麻煩告訴下我~~ajax

相關文章
相關標籤/搜索