(转)【web前端培训之前后端的配合(中)】继续昨日的故事

原文地址:http://www.cnblogs.com/yexiaochai/archive/2013/06/06/3120266.html

 

前言

接着昨天的写:【web前端培训之前后端的配合(上)】以我们熟悉的Datalist说明问题吧

经过昨天晚上的学习,我们形成了一个伪datalist,但是他没有事件绑定,甚至每个datait还多出了一个无意义的div!!!

其实datalist多出一个div我是可以接受的,但是dataitem多出一个我这里就不太能接受了,所以里面还有很多东西可以继续深入。

昨天说了那么久也没有扯到和后端的配合,今天需要补足,于是进入今天的学习吧。

题外话

今天碰到一个有趣的东西,也许各位已经知道了,但是我这里还是提出来,老夫脸皮厚是不怕人笑话的哟。

  • 解析HTML结构。
  • 加载外部脚本和样式表文件。
  • 解析并执行脚本代码。
  • 构造HTML DOM模型。
  • 加载图片等外部文件。
  • 页面加载完毕。

其中图片会最后加载,无论如何都会最后加载,我当时想最开始就加载我一个广告(这个广告是个卷轴,会慢慢展开,会有黑色的层遮盖)。

我当时虽然将它放到了最前面,却给他的display设置为none了,于是我满以为他会最先加载的,结果却是最后加载(因为我js在最后控制的显示)。

我这里就犯了一个错误,因为在display为none的情况下,图片是不会加载的。

复制代码
1 <html xmlns="http://www.w3.org/1999/xhtml">
2 <head>
3     <meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
4     <title>测试页面</title>
5 </head>
6 <body>
7     <div style=" background-image: url(http://pic002.cnblogs.com/images/2012/294743/2012032201481631.png); display: none;"></div>
8 </body>
9 </html>
复制代码

PS:注意,我这里的说的都是背景,不是img标签,img标签都会加载的

以上代码开始不会加载背景图片,但是当显示时候起图片便会加载了。所以我们若是有些隐藏的dom元素需要加载而且里面含有大量背景图片。而我们加载时候又不想其感觉加载很慢,就需要做特殊处理啦。

完了,这里还有其它问题:

在动画执行过程中因为下面还有几个js文件需要加载,加载时候动画效果会偶尔出现一点点卡的现象,这块需要处理,我想的是采用异步加载余下js的方法,但是感觉为一个广告又不太划算,不知道各位有什么看法没有。

好了进入今日的正题。

剔除多余的div

首先上一章昨天的图:

最外层div为datalist的,我这里可以接受,但是内层的div,我这里真不能接受了!所以我们想法改变一下,这里也需要考虑到这种场景:

若是外层datalist使用的不是div,而是ul或者dl我们也是必须支持的,因为里面的item是可能出现li的

我们这里做一点简单的处理,若是模板不能形成dom,我们便为之添加div,若是能的话就不需要div了:

复制代码
 1 DataItem.prototype.load = function (index, data) {
 2     this.data = data;
 3     var parentEl = this.parentObj.el; //注意此处是parent已经赋值
 4     var parentId = this.parentObj.id
 5     var id = parentId + this.idPrefix + index; //生成唯一id
 6     this.id = id;
 7     //注意啦,这里根据html片段开始生成最终数据了哦
 8     var templateObj = this.templateObj; //此处的膜拜已经过处理
 9     var tmpHtm = '';
10     $.each(templateObj, function (i, item) {
11         if (item.field) {
12             tmpHtm = tmpHtm + item.html + data[item.field]
13         } else {
14             tmpHtm = tmpHtm + item.html;
15         }
16     });
17     var el = $(tmpHtm);
18     //    var el = $('<div></div>'); //形成dom
19     //为了避免id重复,这里对id必须进行处理,我们同时不允许为元素设置id
20     if (!el[0]) {
21         el = $('<div/>');
22         el.html(tmpHtm);
23     }
24     el.attr('id', id);
25     if (this.className)
26         this.el.attr("class", this.className);
27     parentEl.append(el);
28 };
复制代码
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <style type="text/css">
        .box { margin: 10px; padding: 10px; border: 1px solid gray; display: inline-block; }
    </style>
    <script src="js/jquery-1.7.1.min.js" type="text/javascript"></script>
    <script src="js/Datalist.js" type="text/javascript"></script>
    <script type="text/javascript">
        $(document).ready(function () {
            var _url = 'Ajax.aspx?sql=select * from bigType';
            $.getJSON(_url, function (data) {
                var d = new Datalist();
                d.tag = '<ul/>'
                d.template = 'tmp';
                d.dataSource = data;
                d.bind();
            });
        });
    </script>
</head>
<body>
    <textarea id="tmp">
<li class="box">
        <h3>
            {%title%}</h3>
 
        <dl>
            <dt>{%id%}</dt>
            <dd>{%title%}
            </dd>
        </dl>
    </li>
</textarea>
</body>
</html>
View Code

 

现在这种结构式可以接受的。。。好啦,我们现在来为我们里面的元素绑定事件吧:

事件绑定

无论是我们的datalist还是我们的dataitem,他们都是拥有事件的,我们应该可以像.net那样可以找到各自里面的某个标签,并且操作他呢,我们并且也可以datalist嵌套的。

首先我们为datalist添加两个参数,一个用于自己的事件,一个用于定义其item的事件,因为他的item事件应该大致相同:

复制代码
var Datalist = function () {
    this.id = new Date().getTime().toString();
    this.items = []; //所具有的dataitem的项目
    this.dataSource = null; //各位对他熟悉吧
    this.container = $("body"); //我们的datalist的容器,没有指定的话就放在body里面
    this.style = {}; //可以为其设置样式这里考虑的好像有点多了
    this.attribute = {}; //为其设置属性
    this.className = '';
    this.itemClass = ''; //子元素的class
    this.tag = '<div></div>';
    this.template = ''; //可以在此设置,也可以指定容器id,然后由容器寻找

    this.itemEvent = {};
    this.itemElementEvent = {};
};
复制代码

注意最后我们新增加的方法哦,itemEvent用于datalist的item的,比如上面的li标签,后面的用于其中item里面的元素,比如h3标签。

我们在.net中定义事件好像也是放出来的呢,我们这先看看怎么使用吧:

复制代码
 1 $(document).ready(function () {
 2     var _url = 'Ajax.aspx?sql=select * from bigType';
 3     $.getJSON(_url, function (data) {
 4         var d = new Datalist();
 5         d.tag = '<ul/>'
 6         d.template = 'tmp';
 7         d.dataSource = data;
 8         d.itemEvent.clickLi = {
 9             eventType: 'click',
10             funcName: function (data, e, sender) {
11 
12                 var s = '';
13             }
14         };
15         d.bind();
16     });
17 });
复制代码
复制代码
 1 DataItem.prototype.bindEvent = function () {
 2     var scope = this;
 3     var el = scope.el; //获取当前元素
 4     var data = scope.data; //当前行数据
 5     var events = scope.event;
 6     $.each(events, function (k, v) {
 7         var type = v.eventType;
 8         var func = v.funcName;
 9         var sender = v.sender; //最初调用对象
10         if (func && typeof func == 'function') {
11             if (type == 'ready') {
12                 func.call(scope, params, e, original);
13             } else {
14                 el.unbind(type).bind(type, function (e) {
15                     func.call(scope, data, e, sender);
16                 });
17             }
18         }
19     });
20 };
复制代码

我们看到这里基本上达到了我们的要求了,而且传了很多有意义的参数回来,接下来我们再加一点东西便来试试吧:

这里贴上完整代码啦:

js:

  1 /// <reference path="jquery-1.7.1.min.js" />
  2 var DataItem = function () {
  3     this.data = null;
  4     this.el = null;
  5     this.id = '';
  6     this.parentObj = null;
  7     this.idPrefix = '_item_'; //id前缀
  8     this.className = '';
  9     this.event = {};
 10     this.elementEvent = {};
 11 };
 12 
 13 DataItem.prototype.load = function (index, data) {
 14     this.data = data;
 15     var parentEl = this.parentObj.el; //注意此处是parent已经赋值
 16     var parentId = this.parentObj.id
 17     var id = parentId + this.idPrefix + index; //生成唯一id
 18     this.id = id;
 19     //注意啦,这里根据html片段开始生成最终数据了哦
 20     var templateObj = this.templateObj; //此处的膜拜已经过处理
 21     var tmpHtm = '';
 22     $.each(templateObj, function (i, item) {
 23         if (item.field) {
 24             tmpHtm = tmpHtm + item.html + data[item.field]
 25         } else {
 26             tmpHtm = tmpHtm + item.html;
 27         }
 28     });
 29     var el = $(tmpHtm);
 30     //    var el = $('<div></div>'); //形成dom
 31     //为了避免id重复,这里对id必须进行处理,我们同时不允许为元素设置id
 32     if (!el[0]) {
 33         el = $('<div/>');
 34         el.html(tmpHtm);
 35     }
 36     el.attr('id', id);
 37     if (this.className)
 38         this.el.attr("class", this.className);
 39     parentEl.append(el);
 40     this.el = el;
 41     //增加相应事件绑定
 42     this.bindEvent();
 43     this.bindElementEvent();
 44 };
 45 
 46 DataItem.prototype.bindEvent = function () {
 47     var scope = this;
 48     var el = scope.el; //获取当前元素
 49     var data = scope.data; //当前行数据
 50     var events = scope.event;
 51     $.each(events, function (k, v) {
 52         var type = v.eventType;
 53         var func = v.funcName;
 54         var sender = v.sender; //最初调用对象
 55         if (func && typeof func == 'function') {
 56             if (type == 'ready') {
 57                 func.call(scope, params, e, original);
 58             } else {
 59                 el.unbind(type).bind(type, function (e) {
 60                     func.call(scope, data, e, sender);
 61                 });
 62             }
 63         }
 64     });
 65 };
 66 //绑定item里面的某一个标签
 67 DataItem.prototype.bindElementEvent = function () {
 68     var scope = this;
 69     var data = scope.data; //当前行数据
 70     var events = scope.elementEvent;
 71     $.each(events, function (k, v) {
 72         var elementkey = v.elementkey; //元素选择器
 73         var type = v.eventType;
 74         var func = v.funcName;
 75         var sender = v.sender;
 76         var id = '#' + scope.id + ' ' + elementkey;
 77         var el = $(id);
 78         if (func && typeof func == 'function') {
 79             if (type == 'ready') {
 80                 func.call(scope, params, e, original);
 81             } else {
 82                 el.unbind(type).bind(type, function (e) {
 83                     func.call(scope, data, e, sender);
 84                 });
 85             }
 86         }
 87     });
 88 };
 89 
 90 var Datalist = function () {
 91     this.id = new Date().getTime().toString();
 92     this.items = []; //所具有的dataitem的项目
 93     this.dataSource = null; //各位对他熟悉吧
 94     this.container = $("body"); //我们的datalist的容器,没有指定的话就放在body里面
 95     this.style = {}; //可以为其设置样式这里考虑的好像有点多了
 96     this.attribute = {}; //为其设置属性
 97     this.className = '';
 98     this.itemClass = ''; //子元素的class
 99     this.tag = '<div></div>';
100     this.template = ''; //可以在此设置,也可以指定容器id,然后由容器寻找
101 
102     this.itemEvent = {};
103     this.itemElementEvent = {};
104 };
105 
106 //好了,我们第一步需要
107 Datalist.prototype.formatTemplate = function () {
108     var template = this.template;
109     if (template.length < 10) {
110         template = $('#' + template);
111         if (template[0]) template = template.val();
112     }
113     var reg = /\{%[\w]*\%}/;
114     var para = reg.exec(template);
115     var html = template;
116     var templateObj = [];
117     while (para && para.length > 0) {
118         var len = para.index;
119         var tmp = {};
120         tmp.html = html.substr(0, len);
121         tmp.field = para[0].substr(2, para[0].length - 4);
122         templateObj.push(tmp);
123         html = html.substr(len + para[0].length);
124         para = reg.exec(html);
125     }
126     tmp = {};
127     tmp.html = html;
128     templateObj.push(tmp);
129     this.templateObj = templateObj; //注意我们的datalist多了一个东西了哦
130 };
131 
132 Datalist.prototype.bind = function () {
133     //初始化属性等操作,我们暂时忽略之
134     //...............
135     this.initElement(); //初始化元素
136     this.formatTemplate();
137     var scope = this;
138     var itemIndex = 0;
139     var container = this.container;
140     container.append(this.el); //将datalist装入容器
141 
142     $.each(this.dataSource, function (k, v) {
143         var item = new DataItem(); //实例化了一个item了哦
144         item.parentObj = scope;
145         item.templateObj = scope.templateObj;
146         item.event = scope.itemEvent;
147         item.elementEvent = scope.itemElementEvent;
148         item.load(itemIndex, v);
149         scope.items.push(item);
150         itemIndex++;
151     });
152 };
153 
154 Datalist.prototype.initElement = function () {
155     var el = $(this.tag);
156     el.attr('id', this.id);
157     this.el = el;
158     this.initAttribute();
159     this.initStyle();
160 };
161 
162 Datalist.prototype.initAttribute = function () {
163     var scope = this;
164     var element = scope.el;
165     $.each(scope.attribute, function (key, value) {
166         if (typeof (value) == "string")
167             if (value && value.length > 0) {
168                 element.attr(key, value);
169             }
170     });
171 };
172 
173 Datalist.prototype.initStyle = function () {
174     var scope = this;
175     var element = this.el;
176     var style = this.style;
177     $.each(style, function (key, value) {
178         if (value && value.length > 0) {
179             element.css(key, value);
180         }
181     });
182 };
View Code

html:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <style type="text/css">
        .box { margin: 10px; padding: 10px; border: 1px solid gray; display: inline-block; }
    </style>
    <script src="js/jquery-1.7.1.min.js" type="text/javascript"></script>
    <script src="js/Datalist.js" type="text/javascript"></script>
    <script type="text/javascript">
$(document).ready(function () {
    var _url = 'Ajax.aspx?sql=select * from bigType';
    $.getJSON(_url, function (data) {
        var d = new Datalist();
        d.tag = '<ul/>'
        d.template = 'tmp';
        d.dataSource = data;
        d.itemEvent.clickLi = {
            eventType: 'click',
            funcName: function (data, e, sender) {
                var s = '';
            }
        };
        d.itemElementEvent.clickH = {
            elementkey: 'h3',
            eventType: 'click',
            funcName: function (data, e, sender) {
                var s = '';
            }
        };
        d.bind();
    });
});
    </script>
</head>
<body>
    <textarea id="tmp">
<li class="box">
        <h3>
            {%title%}</h3>
 
        <dl>
            <dt>{%id%}</dt>
            <dd>{%title%}
            </dd>
        </dl>
    </li>
</textarea>
</body>
</html>
View Code

好了,我们来检测下今天的学习成果吧。

嵌套的datalist

我们这里搞一个datalist嵌套的实验,并点击每个h3便alert名字:

完整代码:

复制代码
 1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 2 <html xmlns="http://www.w3.org/1999/xhtml">
 3 <head>
 4     <title></title>
 5     <style type="text/css">
 6         .box { margin: 10px; padding: 10px; border: 1px solid gray; display: inline-block; }
 7     </style>
 8     <script src="js/jquery-1.7.1.min.js" type="text/javascript"></script>
 9     <script src="js/Datalist.js" type="text/javascript"></script>
10     <script type="text/javascript">
11         $(document).ready(function () {
12             var _url = 'Ajax.aspx?sql=select * from bigType';
13             $.getJSON(_url, function (data) {
14                 var d = new Datalist();
15                 d.template = 'datalist';
16                 d.dataSource = data;
17                 d.itemElementEvent.clickH3 = {
18                     elementkey: 'h3',
19                     eventType: 'click',
20                     funcName: function (data, el, e) {
21                         alert(el.html());
22                     }
23                 };
24                 d.itemElementEvent.loadItem = {
25                     elementkey: '.wrapper',
26                     eventType: 'ready',
27                     funcName: function (data, el) {
28                         var bigTypeId = data.id;
29                         var url = 'Ajax.aspx?sql=select * from smallType where bigTypeId=' + bigTypeId;
30                         var scope = this;
31                         $.getJSON(url, function (_data) {
32                             var tmp = new Datalist();
33                             tmp.container = el;
34                             tmp.template = 'dataItem';
35                             tmp.tag = '<ul/>'
36                             tmp.dataSource = _data;
37                             tmp.bind();
38                             var s = '';
39 
40                         });
41                     }
42                 };
43                 d.bind();
44             });
45         });
46     </script>
47 </head>
48 <body>
49     
50 <textarea id="datalist">
51     <div class="box">
52         <h3>
53             {%title%}</h3>
54         <div class="wrapper"></div>
55     </div>
56 </textarea>
57     
58 <textarea id="dataItem">
59     <li class="box">
60         <dl>
61             <dt>{%id%}</dt>
62             <dd>
63                 {%title%}</dd>
64         </dl>
65     </li>
66 </textarea>
67 </body>
68 </html>
复制代码
  1 /// <reference path="jquery-1.7.1.min.js" />
  2 var DataItem = function () {
  3     this.data = null;
  4     this.el = null;
  5     this.id = '';
  6     this.parentObj = null;
  7     this.idPrefix = '_item_'; //id前缀
  8     this.className = '';
  9     this.event = {};
 10     this.elementEvent = {};
 11 };
 12 
 13 DataItem.prototype.load = function (index, data) {
 14     this.data = data;
 15     var parentEl = this.parentObj.el; //注意此处是parent已经赋值
 16     var parentId = this.parentObj.id
 17     var id = parentId + this.idPrefix + index; //生成唯一id
 18     this.id = id;
 19     //注意啦,这里根据html片段开始生成最终数据了哦
 20     var templateObj = this.templateObj; //此处的膜拜已经过处理
 21     var tmpHtm = '';
 22     $.each(templateObj, function (i, item) {
 23         if (item.field) {
 24             tmpHtm = tmpHtm + item.html + data[item.field]
 25         } else {
 26             tmpHtm = tmpHtm + item.html;
 27         }
 28     });
 29     var el = $(tmpHtm);
 30     //    var el = $('<div></div>'); //形成dom
 31     //为了避免id重复,这里对id必须进行处理,我们同时不允许为元素设置id
 32     if (!el[0]) {
 33         el = $('<div/>');
 34         el.html(tmpHtm);
 35     }
 36     el.attr('id', id);
 37     if (this.className)
 38         this.el.attr("class", this.className);
 39     parentEl.append(el);
 40     this.el = el;
 41     //增加相应事件绑定
 42     this.bindEvent();
 43     this.bindElementEvent();
 44 };
 45 
 46 DataItem.prototype.bindEvent = function () {
 47     var scope = this;
 48     var el = scope.el; //获取当前元素
 49     var data = scope.data; //当前行数据
 50     var events = scope.event;
 51     $.each(events, function (k, v) {
 52         var type = v.eventType;
 53         var func = v.funcName;
 54         var sender = v.sender; //最初调用对象
 55         if (func && typeof func == 'function') {
 56             if (type == 'ready') {
 57                 func.call(scope, data, sender);
 58 
 59             } else {
 60                 el.unbind(type).bind(type, function (e) {
 61                     func.call(scope, data, e, sender);
 62                 });
 63             }
 64         }
 65     });
 66 };
 67 //绑定item里面的某一个标签
 68 DataItem.prototype.bindElementEvent = function () {
 69     var scope = this;
 70     var data = scope.data; //当前行数据
 71     var events = scope.elementEvent;
 72     $.each(events, function (k, v) {
 73         var elementkey = v.elementkey; //元素选择器
 74         var type = v.eventType;
 75         var func = v.funcName;
 76         var sender = v.sender;
 77         var id = '#' + scope.id + ' ' + elementkey;
 78         var el = $(id);
 79         if (func && typeof func == 'function') {
 80             if (type == 'ready') {
 81                 func.call(scope, data, el, sender);
 82             } else {
 83                 el.unbind(type).bind(type, function (e) {
 84                     func.call(scope, data, el, e, sender);
 85                 });
 86             }
 87         }
 88     });
 89 };
 90 
 91 var Datalist = function () {
 92     this.id = new Date().getTime().toString();
 93     this.items = []; //所具有的dataitem的项目
 94     this.dataSource = null; //各位对他熟悉吧
 95     this.container = $("body"); //我们的datalist的容器,没有指定的话就放在body里面
 96     this.style = {}; //可以为其设置样式这里考虑的好像有点多了
 97     this.attribute = {}; //为其设置属性
 98     this.className = '';
 99     this.itemClass = ''; //子元素的class
100     this.tag = '<div></div>';
101     this.template = ''; //可以在此设置,也可以指定容器id,然后由容器寻找
102 
103     this.itemEvent = {};
104     this.itemElementEvent = {};
105 };
106 
107 //好了,我们第一步需要
108 Datalist.prototype.formatTemplate = function () {
109     var template = this.template;
110     if (template.length < 10) {
111         template = $('#' + template);
112         if (template[0]) template = template.val();
113     }
114     var reg = /\{%[\w]*\%}/;
115     var para = reg.exec(template);
116     var html = template;
117     var templateObj = [];
118     while (para && para.length > 0) {
119         var len = para.index;
120         var tmp = {};
121         tmp.html = html.substr(0, len);
122         tmp.field = para[0].substr(2, para[0].length - 4);
123         templateObj.push(tmp);
124         html = html.substr(len + para[0].length);
125         para = reg.exec(html);
126     }
127     tmp = {};
128     tmp.html = html;
129     templateObj.push(tmp);
130     this.templateObj = templateObj; //注意我们的datalist多了一个东西了哦
131 };
132 
133 Datalist.prototype.bind = function () {
134     //初始化属性等操作,我们暂时忽略之
135     //...............
136     this.initElement(); //初始化元素
137     this.formatTemplate();
138     var scope = this;
139     var itemIndex = 0;
140     var container = this.container;
141     container.append(this.el); //将datalist装入容器
142 
143     $.each(this.dataSource, function (k, v) {
144         var item = new DataItem(); //实例化了一个item了哦
145         item.parentObj = scope;
146         item.templateObj = scope.templateObj;
147         item.event = scope.itemEvent;
148         item.elementEvent = scope.itemElementEvent;
149         item.load(itemIndex, v);
150         scope.items.push(item);
151         itemIndex++;
152     });
153 };
154 
155 Datalist.prototype.initElement = function () {
156     var el = $(this.tag);
157     el.attr('id', this.id);
158     this.el = el;
159     this.initAttribute();
160     this.initStyle();
161 };
162 
163 Datalist.prototype.initAttribute = function () {
164     var scope = this;
165     var element = scope.el;
166     $.each(scope.attribute, function (key, value) {
167         if (typeof (value) == "string")
168             if (value && value.length > 0) {
169                 element.attr(key, value);
170             }
171     });
172 };
173 
174 Datalist.prototype.initStyle = function () {
175     var scope = this;
176     var element = this.el;
177     var style = this.style;
178     $.each(style, function (key, value) {
179         if (value && value.length > 0) {
180             element.css(key, value);
181         }
182     });
183 };
js

 

结语

本来今天想结束的,结果不知不觉时间就没有了,看来的加快点速度啊。。。。

posted on 2013-06-11 12:53  黑子范  阅读(159)  评论(0编辑  收藏  举报

导航