【前端模板之路】一、重构的兄弟说:我才不想看你的代码!把HTML给我交出来!

写在前面

随着前端领域的发展和社会化分工的需要,继前端攻城湿之后,又一重要岗位横空出世——重构攻城湿!所谓的重构攻城湿,他们的一大特点之一,就是精通CSS配置文件的编写。。。前端攻城湿跟重构攻城湿是一对好基友,你写逻辑来,我写样式。

好吧,本文并不是介绍重构攻城湿这个职业的,而是通过一个简单的场景来说说:

1. 在用前端模板之前,我们是肿么动态创建节点的

2. 为什么要使用前端模板

一个简单的场景

下面这张图片看着应该很眼熟吧?没错,是从mac QQ的好友列表里面截出来的。作为一名前端攻城湿,相信不少童鞋的第一反应是:需要用什么样的html结构来标识它?样式要怎么写?

好吧,就假设我们可以用下面的dom结构来标识这个“好友”,不考虑其合理性,同时,样式部分我们华丽丽地直接忽略

<div>
    <img src="http://www.example.com/img/bg.png" />
    <h3>小卡的测试号</h3>
    <div>大家好,我是个性签名</div>
</div>

大家知道,我们的QQ好友列表是不固定的,于是必须得进行“动态创建”。我们通常会肿么做呢?

老湿说:createElement神马的是王道

老湿曾经谆谆教诲我们说,不要通过innerHTML来创建节点,因为那会让代码变得混乱不堪。好歹也拿过优秀少先队员的称号,当然得听老湿话了,于是我乖乖地写下如下代码:

var card = document.createElement('div');

var avatar = document.createElement('img');  // 头像
avatar.src = 'http://www.example.com/img/header.png';
card.appendChild(avatar);

var nick = document.createElement('h3');  // 昵称
var nickTxt = document.createTextNode('小卡的测试号');
nick.appendChild(nickTxt);
card.appendChild(nick);

var signature = document.createElement('div');  // 个性签名
var signatureTxt = document.createTextNode('大家好,我是个性签名');
signature.appendChild(signatureTxt);
card.appendChild(signature);

createElement的问题

筋疲力竭地敲完上面地代码,我露出了满足地微笑:老湿你坑我哪! 就这么几个破节点,让我敲这么多代码?

好吧,后来我才知道我错怪老湿了,他让我用createElement地方式来创建节点,但没说过让我人肉敲啊。人类进步的源动力之一就是懒,计算机存在的很大价值就是为了解放生产力,干嘛不换个思路,让代码来帮我们生成代码呢?代码生成代码?听着好玄乎,其实并不难,请看《【前端模板之路】二、人肉非智举,让代码帮我们写代码才是王道》

好吧,即使我们真的做到了“让代码为我们写代码”,看看上面人肉敲的那坨东西,有没有发现什么问题?

自言自语神马的最讨论了,最大的问题在于:dom结构很不直观,你压根不知道你创建出来的节点结构是神马样子的!!

换别人接手你的代码,第一件事就是得把上面的代码跑一遍,然后耐着性子打开控制台把dom结构翻一遍,才能知道你上面那坨代码究竟造了个什么鬼东西出来。好吧,那我改。。。

总结下:费体力,不直观

那些年,我们一起用过的innerHTML

毛少将说过:innerHTML是个好属性!看看换做innerHTML我们会肿么做?var card = document.createElement('div');

card.innerHTML = '<img src="http://www.example.com/img/bg.png" />' +
                    '<h3>小卡的测试号</h3>' +
                    '<div>大家好,我是个性签名</div>';

哇!只需要几行代码就搞定了,麻麻再也不用担心我加班了!写代码,so easy!

一切似乎很美好,但是,慢着!假如我们现在要创建一批节点呢?上面把资料都写死了不通用啊!

很简单嘛,把动态变化的那几个字段提取出来不就得了,如下代码所示,瞬间高档大气上档次

function createCard(avatarURL, nick, signature){

    var card = document.createElement('div');
    card.innerHTML = '<img src="'+ avatarURL +'" />' +
                        '<h3>'+ nick +'</h3>' +
                        '<div>'+ signature +'</div>';
    return card;
}
createCard('http://www.example.com/img/bg.png', '小卡的测试号', '大家好,我是个性签名');

innerHTML的问题

很好,字符串相加,一堆引号,似乎看出点问题来了。上面的场景算是很简单的,动态变化的内容不过就头像、昵称、个性签名三个,但现实世界远比我们预料的要复杂得多。如果我们想把显示的好友资料再扩展以下,加上在线状态、是否会员、是否手机在线,那么,上面的代码可能变成这样(只是yy的)

function createCard(avatarURL, nick, signature, onlineState, isVIP, isMobileOnline){

    var onlineTxt = '';
    switch(onlineState){
        case 0:
            onlineTxt = '在线';
            break;
        case 1:
            onlineTxt = '离线';
            break;
        case 0:
            onlineTxt = '忙碌';
            break;
        default:
            case 0:
            onlineTxt = '在线';
            break;
    }
    var card = document.createElement('div');    // 有性能洁癖的兄弟看到下面的代码表拿砖头砸我

    card.innerHTML = '<img src="'+ avatarURL +'" />' +    // 头像
                        '<h3>'+ nick +'</h3>' +    // 昵称
                        '<div>'+ onlineTxt +'</div>' +    // 在线状态
                        '<div>'+ (isVIP ? '会员' : '非会员') +'</div>';    // 是否会员

    if(isMobileOnline){
        card.innerHTML += '<div>'+ (isMobileOnline ? '手机在线' : '') +'</div>';    // 是否手机在线
    }

    card.innerHTML += '<div>'+ signature +'</div>';    // 个性签名
    return card;
}

显然,代码开始变得有点混乱了,再加上id、class以及其他属性,相信我,绝对会很壮观。。。

缺点总结:可维护性较差(解决方案在后文会说到)

重构的童鞋说:我不想看你的代码!

上面简单对比了createElement、innerHTML创建节点的两种方式,细心的童鞋不难看出笔者的倾向性——innerHTML。

随着前端领域的发展和社会化分工的需要,继前端攻城湿之后,又一重要岗位横空出世——重构攻城湿!所谓的重构攻城湿,他们的一大特点之一,就是精通CSS配置文件的编写。。。

前端攻城湿跟重构攻城湿是一对好基友,你写逻辑来,我写样式。

>>重构的兄弟说:把你的HTML交出来!

于是,我把之前的那段代码给他,就是这货

    var card = document.createElement('div');
    card.innerHTML = '<img src="'+ avatarURL +'" />' +
                        '<h3>'+ nick +'</h3>' +
                        '<div>'+ signature +'</div>';
    return card;   

>>重构的兄弟:。。。谁要看你的代码,我要看HTML结构!!

>>我:。。。要命有一条~~要不你把createCard 调用一下?

>>重构的兄弟怒了:想试试千年杀?!!

>>我:??!!擦,别~~你骚等~~~

于是,我简单倒腾了一下,给了它下面这东西,还是最开头的那段HTML,只不过把所有动态变化的内容,用$XX的形式代替了

<div id="my_tmpl">
    <div>
        <img src="${avatar}" />
        <h3>${nick}</h3>
        <div>${signature}</div>
    </div>
</div>

重构的童鞋拿到他要的东西,心满意足的就回去写他的CSS去了,那我们呢?也很简单,原来拼字符串,现在正则换变量,如下

var data = {
    avatar: 'http://www.example.com/img/bg.png',
    nick: '小卡的测试号',
    signature: '大家好,我是个性签名'
};
var html = document.getElementById('my_tmpl').innerHTML;
html = html.replace(/\$\{(.+?)\}/g, function(all, $1){ // 将${XX}替换成data[XX]
    return data[$1];
});

这里我们已经隐约看到了前端模板的身影了,结构、样式与逻辑分离的第一步已经实现了,重构的童鞋根据约定好的HTML模板写CSS样式,前端的童鞋负责往模板里填内容、更新内容,绑定事件,处理用户交互等,这样做的好处很明显:

1. 结构、表现、逻辑分离,便于重构、前端童鞋的分工配合

2. 更好的可维护性,再也不用被一堆createElement,或破碎的字符串之间绕晕了

原来就是这货:前端模板引擎的本质

看着前面的${avatar}、${nick}等,很多童鞋应该有似曾相似之感。没错,这里用的替换标识,跟jQuery Tmpl的变量替换标识是一样的,可参考https://github.com/BorisMoore/jquery-tmpl

前端模板引擎的本质,就是变量替换而已。

看到这里,你是不是觉得:原来这货就是前端模板引擎啊,不过如此嘛!如果你有这种感觉,那么:

1. 你以为前端模板引擎有多玄乎啊,本来绕来绕去,最终就是变量替换那么回事

2. Too young,to simple,sometimes, too naive. 前端模板引擎做的事情,除了变量替换之外,还要处理逻辑判断、循环、模板嵌套、预渲染预处理等一堆东东,光有变量替换,实在不好意思说是前端模板引擎。。

好了,之前还有个问题等着解决,ctrl+f找到下面这段代码

    if(isMobileOnline){
        card.innerHTML += '<div>'+ (isMobileOnline ? '手机在线' : '') +'</div>';    // 是否手机在线
    }

这其实就是逻辑判断要做的事情,假设用的是jQuery Tmpl,下面这样写就可以了

<div>
{{if isMobileOnLine}}手机在线{{/if}}
</div>

jQuery Tmpl的用法,这里不打算展开,可参考:http://www.cnblogs.com/think8848/archive/2011/07/17/2108570.html

jQuery Tmpl的源码剖析,请见后续文章~~

写在后面

本文通过一个场景的场景,引出我们为什么要使用前端模板,至于前端模板的设计这里暂时不提及,留待后续文章展开。

想到哪写到哪,逻辑略凌乱,包涵~码字不易,请随手点推荐~~

时间: 2024-08-24 22:07:28

【前端模板之路】一、重构的兄弟说:我才不想看你的代码!把HTML给我交出来!的相关文章

【前端模板之路】二、人肉非智举,让代码帮我们写代码才是王道

写在前面 在前面一篇文章<[前端模板之路]一.重构的兄弟说:我才不想看你的代码!把HTML给我交出来!>中,我们举了一个人肉各种createElement的例子,那繁琐程度绝对是惨绝人寰.人生本就苦短,每天加班又占据了不少时间,这么折腾下去,还让人怎么活.面对这种场景,我们该怎么做. 无需复杂的构建工具,仅几个简单的工具函数,帮我们告别重复意义的劳动:让代码帮我们写代码! 从最简单的例子说起 让代码帮我们写代码,似乎很豪迈的话,但相信部分童鞋听着还是有些丈二和尚摸不着头脑.那我们暂且抛开这句不

前端模板的原理与实现

时下流行什么react, avalon, angular, vue什么,其核心都离不开前端模板.理解前端模板,是我们了解MV* 的关键. 前端框架最重要的目的是将页面渲染出来."渲染"(render)这个词最初不是前端的东西的.前端之前叫做切图,将设计师做的PSD变成一个静态页面,然后加上动态交互.但是我们有许多数据是来自后端,如何将数据加入静态页面呢?于是又多了一套工序叫"套页面".套页面的过程实际就是将静态页面变成切割成一块块,每一块都是一个php,jsp或vm

数据库-vs2010的gridview加模板列实现文件上传的功能,如图,求后台具体代码,谢谢!!!

问题描述 vs2010的gridview加模板列实现文件上传的功能,如图,求后台具体代码,谢谢!!! vs2010加access想实现图上的功能,即在gridview的模板列添加了一个fileupload控件,实现浏览文件然后上传到数据库里面,求高人给出后台的具体代码,谢谢!!! 解决方案 http://download.csdn.net/detail/sanyingwenkui/2585448

前端进阶之路:如何高质量完成产品需求开发

写在前面 作为一个互联网前端老鸟,这么些年下来,做过的项目也不少.从最初的我的QQ中心.QQ圈子,到后面的QQ群项目.腾讯课堂.从几个人的项目,到近百号人的项目都经历过. 这期间,实现了很多的产品需求,也积累了一些经验.这里稍作总结,希望能给新入行的前端小伙伴们一些参考. 做好需求的关键点 要说如何做好一个需求,展开来讲,可以写好几篇文章,这里只挑重点来讲. 最基本的,就是把握好3W:what.when.how. what:做什么? when:完成时间? how:如何完成? 需求场景假设 为了下

前端这条路怎么走,作为一名后端er,说说我的见解

近期都游荡在各大群里看大家的讨论,经常看到关于程序员生涯的一些讨论,颇有感触,最近的国庆的确过得有些堕落,都没怎么更新,仔细相信还是应该分享点经验给大家的!想必大家都经历过面试,这是进入一家公司的必要门槛,面试官总会问"你的职业规划是什么",那么你怎么回答? 技术经理,项目经理,架构师,有时候这些回到不是你想到的,而是你身边的人说多了,就脱口而出. 我们为何需要职业规划,我在之前的文章中有说过,我们程序员不可能写一辈子代码,我们不是在美国,在美国你就算50多少,60多少也能很有底气的写

前端修炼之路:无需一行代码,教你手写克劳德

写在前面: 原谅我是个标题党,这篇不是什么技术贴来的,所以当然无需一行代码..连续写了好几篇技术随笔,往博客园管理员放过,我下次一定好好继续写技术总结~~~ 背景:悠记得去年6月的某个周末,因为项目的遗留需求,一个人跑到公司加班.那是个安静的下午,倒上一杯咖啡,一个人面对着电脑静静地敲着代码.没有闪动的RTX,没有心急火燎的电话.没有干扰,就连编码似乎也是一件享受的事情. 很快需求就做完了,正打算收拾东西回去,看到柜子上已经蒙上薄薄一层灰尘的板子,想起自毕业后,将近一年没有碰过他了,心血来潮,就

王利芬:创业路困难无大小之分 专注才有商机

腾讯科技讯(扶摇) 4月20日消息,由http://www.aliyun.com/zixun/aggregation/32866.html">亿邦动力网主办的中小企业电子商务领域顶级盛会"第七届中小企业电子商务大会"在北京石景山区万达铂尔曼大饭店隆重召开. 优米网创始人王利芬(微博)在回答现场观众提问时表示,创业路上困难无大小之分.再小的困难,跨不过去你就失败:再大的困难,跨过去了就算成功. 优米网创始人 王利芬(腾讯科技配图) 对于如果寻找商机,王利芬表示,商机在专注

王利芬:创业路困难无大小之分专注才有商机

腾讯科技讯(扶摇) 4月20日消息,由亿邦动力网主办的中小 企业电子商务领域顶级盛会"第七届中小企业电子商务大会"在北京石景山区万达铂尔曼大饭店隆重召开. 优米网创始人王利芬在回答现场观众提问时表示,创业路上困难无大小之分.再小的困难,跨不过去你就失败:再大的困难,跨过去了就算成功.优米网创始人 王利芬(腾讯科技配图)对于如果寻找商机,王利芬表示,商机在专注里!腾讯科技将对本次盛会进行现场图文+微博直播.以下是文字实录:王利芬:各位来宾,大家 下午好!非常高兴来参加这个活动. 这不是谦

我的Node.js学习之路(三)--node.js作用、回调、同步和异步代码 以及事件循环_node.js

一,node.js的作用, I/O的意义,(I/O是输入/输出的简写,如:键盘敲入文本,输入,屏幕上看到文本显示输出.鼠标移动,在屏幕上看到鼠标的移动.终端的输入,和看到的输出.等等)   node.js想解决的问题,(处理输入,输入,高并发 .如 在线游戏中可能会有上百万个游戏者,则有上百万的输入等等)(node.js适合的范畴:当应用程序需要在网络上发送和接收数据时Node.js最为适合.这可能是第三方的API,联网设备或者浏览器与服务器之间的实时通信)   并发的意义,(并发这个术语描述的