寫一個方便維護的 jquery 代碼

前言

最近碰到這樣一個項目,業務邏輯所有都搬到前端,後端只提供API。
可是是在已有的項目上面作這樣作,也就是在已有的項目上添加模塊,這個模塊採用先後端分工的方式來作。
由於各類緣由,因此只有 jquery 能夠用一下,萬惡的ie。javascript

jquery代碼示例

先上代碼,若是要運行,須要額外導入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

  1. init(初始化)jquery

  2. render(渲染頁面)ajax

  3. bind(綁定事件)getData(加載數據)後端

  4. 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;
});

最後

這樣子的寫法我以爲仍是比較方便維護的。

若是有什麼想跟我討論的話,請私信。
相關文章
相關標籤/搜索