前言
经过昨天晚上的学习,我们形成了一个伪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>'); //形成dom19 //为了避免id重复,这里对id必须进行处理,我们同时不允许为元素设置id20 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 class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="js/jquery-1.7.1.min.js" type="text/javascript"></script> <script class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="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 class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="js/jquery-1.7.1.min.js" type="text/javascript"></script> <script class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="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 class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="js/jquery-1.7.1.min.js" type="text/javascript"></script> 9 <script class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="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 = ''; //子元素的class100 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
结语
本来今天想结束的,结果不知不觉时间就没有了,看来的加快点速度啊。。。。
共同学习,写下你的评论
评论加载中...
作者其他优质文章