前言
作为前端新人,以往为实现动态页面都需要在js文件中写大量的HTML片段,写起来费劲,读起来也费劲,而轻量级的模板引擎——handlebars.js为我们很好地解决了问题。
Handlebars.js简单demo
首先引入handlebars.js文件,文件可从官方链接下载。
<script type="text/javascript" src="./js/handlebars-v4.0.11.js"></script>
可以handlebars.js并不依赖jquery,可以使用原生js来操作,但是为了简化dom操作,我这里还是使用了jquery.考虑到低版本的IE兼容性的问题最好使用较低级的最新版本。
<script type="text/javascript" src="./assets/js/jquery-1.11.3.min.js"></script>
在body中我们写这样一段代码
<body>
<div class="demo">
<h1>{{title}}</h1>
<p>{{content}}</p>
<img src="{{img_road}}">
</div>
</body>
在js文件中,我们这样来使用handlesbars
$(document).ready(function () {
var div = $(".demo").html();
var template = Handlebars.compile(div);
var context = {
title: "Hello!",
content: "you are using handlebars now!",
img_road: "./images/handlebars_logo.png",
};
var html = template(context);
$(".demo").html(html);
})
使用非常简单易懂,相信大家已经看过其他的相关入门文章或文档,具体内容我不再赘述了。用过handlebars的小伙伴都知道,一个页面如果要用到很多模板,那么就需要在js文件中编写大量重复的 模板预编译、解析代码,因此,我参考网上的代码,编写了一个通用的Handlebars-jquery插件,以处理大多数情况的模板引擎使用情况。
handlebars-jquery插件
(function($){
var compiled = {};
$.fn.handlebars = function (template, data , helper) {
if(template instanceof jQuery){
template = $(template).html();
}
if(helper instanceof Array){
$.each(helper,function (index,value) {
if(value.name && value.callback){
Handlebars.registerHelper(value.name, value.callback);
}
});
}else if(typeof helper === 'object' && helper.name && helper.callback){
Handlebars.registerHelper(helper.name, helper.callback);
}
compiled[template] = Handlebars.compile(template);
this.html(compiled[template](data));
if(helper instanceof Array){
$.each(helper,function (index,value) {
if(value.name && value.callback){
Handlebars.unregisterHelper(value.name);
}
});
}else if(typeof helper === 'object' && helper.name && helper.callback){
Handlebars.unregisterHelper(helper.name);
}
}
})(jQuery)
这里稍微解释下插件,本插件采用匿名函数自执行的方法来编写,目的是利用局部变量的特性来防止代码冲突。查看jquery源码可知,$代表jquery对象,$.fn代表jquery构造函数的原型(源码如是写到:jQuery.fn = jQuery.prototype),$.fn.handlebars就相当于为jquery构造函数的原型定义了一个名为handlebars的函数,该方法接收三个参数,第一个参数为需要预编译的对象,data为需要放置的数据,helper为registerHelper接收的自定义helper的相关定义,可以是object也可以是Array。
具体使用如下,我以我最近所做的项目中使用的bootstrap轮播图为例
<div id="myCarousel" class="carousel slide" data-ride="carousel" data-interval="5000">
</div>
<!-- 轮播图 -->
<script id="carousel-model" type="text/x-handlebars-template">
<ol class="carousel-indicators">
{{#each this}}
<li data-target="#myCarousel" data-slide-to="{{@index}}" class="{{active @index}}"></li>
{{/each}}
</ol>
<div class="carousel-inner">
{{#each this}}
<div class="item {{active @index}}">
<img src="{{img_laod}}"/>
<div class="carousel-caption">
<span>{{title}}</span>
<p>{{time}}</p>
</div>
</div>
{{/each}}
</div>
</script>
如果要使用外部模板,需要申明type为text/x-handlebars-template
在js文件的$(document).ready()回调函数中这样来实现功能
/**
* 请求后端获取页面数据
*/
var option = getBASEGETAJAX();
option.url = './json/home_page.json';
option.success = function (data) {
/**
* 轮播图
* */
$('#myCarousel').handlebars($('#carousel-model'), data.show, {
name: 'active',
callback: function (index) {
if (index == 0) {
return 'active';
} else {
return '';
}
}
})
}
option.error = function (res) {
console.log(res)
}
$.ajax(option);
其中getBASEGETAJAX的代码为
var BASEGETAJAX = {
dataType:"json",
type:"GET",
data:{}
}
/**
* 获得基础GET method ajax对象
* @return object [基础GET method ajax对象]
*/
function getBASEGETAJAX(){
var newObject = $.extend(true,{},BASEGETAJAX);
return newObject;
}
home_page.json文件内容为
{
"show":[
{"title":"1","img_laod":"./assets/images/u3040.jpg","time":"2009年1月27日"},
{"title":"2","img_laod":"./assets/images/u3041.jpg","time":"2009年1月27日"},
{"title":"3","img_laod":"./assets/images/u3040.jpg","time":"2009年1月27日"}
]
}
效果如下
另外,编写了一个可脱离jquery使用的HandleBarsHelper方法,不做具体演示了
/**
*简化handlebars的操作,此方法可脱离jquery使用,已编写jquery插件替代,操作更加简便
* @deprecated
* @param {object} obj [需要包含以下属性]
*
* @param {element} obj.origin [模板对象]
* @param {object} obj.data [需要插入的数据]
* @param {element} obj.goal [可缺省,缺省为origin,模板作用的对象]
* @param {object} obj.helper [可缺省,registerHelper相关对象]
*
* @param {string} obj.helper.name [需要registerHelper的模块名]
* @param {function} obj.helper.callback [registerHelper回调函数]
* @return
* */
function HandelBarsHelper(obj) {
if (typeof obj.origin != 'undefined'&&typeof obj.data != 'undefined'){
if(typeof obj.goal == 'undefined'){
obj.goal = obj.origin;
}
if(typeof obj.helper != 'undefined'){
Handlebars.registerHelper(obj.helper.name,obj.helper.callback);
}
var origin = obj.origin;
var goal = obj.goal;
var data = obj.data;
var template = Handlebars.compile(origin.innerHTML);
var html = template(data);
goal.innerHTML = html;
}
}
目前的方法通用性还不是很高,如果有更通用的方法来解决问题,希望各位博友提出自己宝贵的意见。