一般来说,我们做网页的流程是这样的
设计稿->静态网页->动态网页
从设计稿到静态网页的过程,相对来说还是比较愉快的,因为你可以看到一个美丽的网页慢慢呈现的过程。但是从静态网页到动态网页的过程相对来说就有些令人讨厌了。以前,我们都是拼接字符串,然后用innerHTML的方式生成网页。那样的代码真的很丑陋,而且你又不能直接预览静态网页。后来,有了JS模板,我们写起来可能就相对优雅一些,我们可以把代码写在这样的script标签里面。
<script type="text/x-jquery-tmpl" id="tpl2">
<div class="row video-entry-row">
<div id="video_${id}" data-video-id="${id}" class="col-xs-12">
<div class="media video-entry">
<div class="pull-left video-left">
<a href="###" class="thumbnail">
<img
class="media-object img-responsive"
src="${albumUrl}" alt="teaching"
onerror="this.onerror=null;this.src='img/video-preview-unavailable.png';">
</a>
<button data-toggle="popover"
class="popover-trigger btn btn-default btn-xs avideo"
data-original-title="" title="">Created:${vCount}</button>
<br>
<a href="create_en.html?vid=${id}" class="btn btn-primary btn-xs avideo">Create</a>
<div class="thumbnail-callout">
</div>
</div>
<div class="media-body">
<h6>
<span class="title">${title}</span>
<small class="duration">${$item.transTime()}</small>
</h6>
<div class="description">${description}</div>
</div>
</div>
</div>
</div>
</script>
到此,似乎已经很方便了。可是,我们仍然有点不满意。因为我们不能直接把html代码写在正常的标签里面,意味着我们不能像静态网页去浏览,而且我们必须把代码从正常的标签里面移到script标签里面去。
基于此,我有了一个想法,为什么不直接解析正常的dom,然后填充动态的数据呢?!于是有了下面的写法:
<div id="list">
<div class="day">
<div class="dayTitle">
<a data="date">日期:2018年10月14日</a>
</div>
<div class="postTitle">
<a class="postTitle2" data="title">Form表单之复选框checkbox操作</a>
</div>
<div class="postCon">
<div class="c_b_p_desc">
<div data="isEdit"><span data="desc" val="false">摘要: </span><span data="desc" contenteditable="true"
val="true">摘要: </span></div>
</div>
</div>
<div class="clear"></div>
<div class="postDesc"><span data="fav">0</span> posted @ <span data="time">2018-10-14 23:14</span> <a
rel="nofollow" class="edit" data="edit">编辑</a></div>
<div class="clear"></div>
</div>
</div>
我们通过data属性把数据跟dom关联起来,个人觉得这是最简的写法了。你可能觉得两个大括号不是更简单吗?问题是,那种不是标准的html,意味着他不能正常解析,而且其实看起来挺恶心的,在你没有映射数据的时候,看起来就是一坨屎。我们这种写法的好处在于,他在没有数据的时候,看起来仍然是一个正常的网页。意味着你只要在你静态网页的基础上添加一个属性就OK了,是不是很优雅~~
好了,事情好像可以到此为止了。哦,不对,要更新数据怎么办。OK,那我们通过上面的写法,已经把dom跟数据映射起来了,当然也可以通过数据找到要更新的dom了,所以只要定义一个类似这样的函数就OK了。
function updateData(data) {
var args = [];
for (var i = 1; i < arguments.length; i++) {
args.push(arguments[i]);
}
if (args.length) {
mapDom(data, data._dom, null, args)
} else {
mapDom(data, data._dom)
}
}
当然,反过来,我们也可以通过dom找到对应的数据了~
function getData(dom){
for(var i=0;i<_m.length;++i){
if(_m[i].dom==dom){
return _m[i].data;
}
}
}
好了,事情好像真的可以到此为止了。可是,我们是不是经常会遇到很多页面公用一个模块。我总是在想,要是能从其他页面直接拖过来就好了。嗯,当然,这个想法就要借助ide了,事情就会变得复杂了。所以,纯粹一点的方法就是定义一个标签。其他页面引进去就好了。类似这样~~
<post c="7" id="post1"></post>
OK,现在我们终于可以实现组件化了。当然我们还要先做一些事,就是把对应的标签解析成相应的模块。嗯,这个其实就是把上面的过程封装成一个对象就OK了。
var post=new MMM("post",t, function(){
var n=parseInt(this.container.attr("c"));
if(!n){
n=100;
}
var o={
"date": "2015-09-09",
time: '2015-09-09 08:08',
title: 'JAVA 入门手册',
desc: '很快,我们就将进入JAVA的新世界~~',
isEdit: false,
fav:0,
_events:_events
};
var t=Date.now();
var arr=[];
for(var i=0;i<n;++i){
arr.push(deepClone(o));
}
this.setData(arr);
});
然后通过标签找到对应的模块就好了~
我们好像还漏了一件事,事件交互呢?没事,我们可以在data里面定义啊,只要把相应的data字段跟定义的事件绑定起来,就相当于绑定了dom跟事件,如下:
var _events= [{
type: "blur", handler: function (parent, el) {
parent.isEdit = false;
parent.desc = el.text();
updateData(parent, "isEdit", "desc");
//mapData(list, 'list1');
}, "data": "desc"
},{
type: "click", handler: function (parent, el) {
parent.isEdit = true;
console.log("click");
var dom=_getDom(parent,'desc');
updateData(parent, "isEdit");
dom.focus();
}, "data": "edit"
},{
type:'click',handler:function(parent,el){
++parent.fav;
updateData(parent,"fav");
},'data':'fav'
}];
好了,基本就是这样了,最后,代码在这里~~ coding.net/u/guodayang…
本文由 melody 创作,采用 知识共享署名4.0 国际许可协议进行许可
本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名
最后编辑时间为: 2019/02/16 12:05