最近碰到這樣一個項目,業務邏輯所有都搬到前端,後端只提供API。
可是是在已有的項目上面作這樣作,也就是在已有的項目上添加模塊,這個模塊採用先後端分工的方式來作。
由於各類緣由,因此只有 jquery 能夠用一下,萬惡的ie。javascript
先上代碼,若是要運行,須要額外導入mock.js。
jscss
$(function() { var list = { init: function() { // 初始化 this.$list = $("#list"); this.render(); }, render: function() { // 渲染 this.getData(); this.bind(); }, renderData: function(data) { // 渲染數據 var temp = { listTemp: '' } $.each(data, function(i, iObj) { temp.listTemp += '<tr data-id="' + iObj.id + '">'+ '<td>' + iObj.name + '</td>'+ '<td>' + iObj.price + '</td>'+ '<td>' + '<span class="color-simple" style="background-color:' + iObj.color + '"></span>'+ '<span>' + iObj.color + '</span>'+ '</td>'+ '<td>' + iObj.name + '</td>'+ '</tr>'; }); this.$list.html(temp.listTemp); }, bind: function() { // 綁定事件 var self = $(this); this.$list.on("click", "tr", function() { alert($(this).data("id")); }); }, getData: function() { // 獲取數據 var self = this; Mock.mock('http://data.cn', { 'list|1-20': [ { 'id|+1': 1, 'name': '@name', 'price|1-1000': 1000, 'color': '@color', 'remark': '@remark' } ] }); $.ajax({ type: "get", url: "http://data.cn", success: function(data) { self.renderData($.parseJSON(data).list); } }); } } list.init(); });
htmlhtml
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <link rel="stylesheet" type="text/css" href="css/page.css"/> </head> <body> <div> <table class="table" border="1" cellpadding="0"> <thead> <tr> <th>名稱</th> <th>價格</th> <th>顏色</th> <th>備註</th> </tr> </thead> <tbody id="list"> </tbody> </table> <script src="js/jquery.js" type="text/javascript" charset="utf-8"></script> <script src="js/mock-min.js" type="text/javascript" charset="utf-8"></script> <script src="js/list.js" type="text/javascript" charset="utf-8"></script> </div> </body> </html>
css前端
body { margin: 0; font-family: "微軟雅黑"; } .table { width: 80%; margin: 20px auto; border-collapse: collapse; border-spacing: 0; } .table td, .table th { text-indent: 2%; text-align: left; } .table thead tr { height: 40px; } .table .body { height: 400px; overflow: auto; display: block; } .table tbody tr { height: 40px; cursor: pointer; } .table tbody tr:nth-child(2n + 1) { background-color: #eafff4; } .table tbody tr:nth-child(2n) { background-color: #fff; } .table tbody tr:hover { background-color: #b0e5ff; } .table tbody tr span { vertical-align: middle; } .table tbody tr .color-simple { width: 20px; height: 20px; margin-right: 10px; border-radius: 2px; display: inline-block; }
這是一個簡單的例子,首先 js 內部執行順序是這樣的:java
init(初始化)jquery
render(渲染頁面)ajax
bind(綁定事件)getData(加載數據)後端
renderData(渲染數據)緩存
init:函數
初始化,加載一個模塊的開始。
主要用來緩存一些成員變量,若是是 jquery對象的 話就在以前加個 "$",這樣作是爲了跟普通元素區別開來。
render:
渲染頁面,顧名思義,就是渲染頁面的函數。
在這個函數內部調用了 getData() 和 bind() 兩個方法,getData()是爲了去取數據,但爲何要在這裏調用 bind() 方法呢,難道不該該在渲染完數據以後再綁定事件呢,說到 bind() 的時候再說爲何。
若是有另外的子模塊須要渲染的話,也能夠放在這裏加載。 (好比在 list 模塊下面有個 editPrice子模塊,是一個單獨的模塊,就能夠並列着寫,而後在這裏調用。)
$(function() { // 我是父模塊 var list = { init: function() { // 初始化 this.$list = $("#list"); this.render(); }, render: function() { // 渲染 this.getData(); // 我調用了子模塊 editPrice.init(); this.bind(); }, renderData: function() {}, bind: function() {}, getData: function() {} } // 我是子模塊 var editPrice = { init: function() {}, render: function() {}, renderData: function() {}, bind: function() {}, getData: function() {} } list.init(); });
bind:
綁定事件,全部的綁定事件所有都在這裏處理。
這裏定義了一個 「self」 變量,這是由於再綁定事件的 on 的函數內部因爲做用域不一樣,因此調用不了其它 list 對象的成員變量和方法,因此事先緩存了起來,有的人會叫 _this、me、that 這些名字,個人習慣是叫 self。
關於上一點其實還能夠再函數尾部加上 bind() 方法綁定做用域的,這樣就不須要額外申明一個變量了,沒有用是由於我不大習慣。。。
這裏講一下爲何 bind() 方法要放在 render() 裏面,之因此不 renderData() 以後作是由於數據可能會重複調用,好比分頁,就可能會重複調用 renderData() 這個方法,因此才利用了事件委託的辦法。
getData:
獲取數據,就是在這裏用 ajax 和後端進行通訊。
用 Mock.js 去模擬一個後端Api,若是你還不知道這個東西,點這裏。
這裏的 self 跟 bind() 裏的 self 同理,爲了調用成員方法 renderData()。
renderData:
渲染數據,用最原始的方法對代碼拼接HTML。
拼接數據的時候,先後用單引號的話,就能夠不用擔憂會跟裏面 class 或者其它屬性的雙引號起衝突了。
拼接好數據以後再一口氣 html 進事先在 init() 方法緩存好的 jquery對象 裏。
另外: 若是個人模塊要在其它的 js 的裏調用怎麼辦,個人作法是 把數據綁定到 window 對象上。
$(function() { var list = {} list.init(); window.list = list; });
這樣子的寫法我以爲仍是比較方便維護的。
若是有什麼想跟我討論的話,請私信。