为了账号安全,请及时绑定邮箱和手机立即绑定

web前端培训之前后端的配合

标签:
Html/CSS

前言


经过昨天晚上的学习,我们形成了一个伪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

 

结语

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

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消