JavaScript 自制可以替换属性的模板引擎(Template)

Posted 福州-司马懿

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaScript 自制可以替换属性的模板引擎(Template)相关的知识,希望对你有一定的参考价值。

<!DOCTYPE html>
<html>
<head>
<meta charset="utf8">
<style>
body 
	margin: 0;

.goods-list 
	list-style: none;
	margin: 0;
	padding: 0;

.goods-list>li 
	background-image: linear-gradient(to top, gray 2%, transparent 3%);
	background-position: 50% 0%;
	background-size: 98% 100%;
	background-repeat: no-repeat;

.goods-list>li 
	padding: 1rem;
	display: flex;
	/** flex默认是不换行 */
	flex-wrap: wrap;
	align-items: center;

/* 
只要设置了img的宽高,src中的图片就会依此压缩
但对于宽高比不一致的图片,直接就形变了
解决办法:套一层在外面,宽/高自适应,overflow: hidden,使用flex布局进行居中
*/
.goods-img 
	width: 5rem;
	height: 5rem;
	margin-right: 1rem;
	overflow: hidden;
	display: flex;
	justify-content: center;
	align-items: center;

.goods-img>img 
	width: auto;
	height: 100%;

.goods-desc 
	flex-grow: 1;

.goods-name 
	font-size: 130%;
	font-weight: bold;
	margin-bottom: .5rem;

.sale-volume 
	color: gray;
	margin-bottom: .5rem;

.goods-buy 
	display: flex;
	flex-wrap: wrap;
	/** 让元素两边和父容器对齐 */
	justify-content: space-between;

.sale-price 
	width: 15rem;
	margin-bottom: .5rem;

.sale-price-now 
	font-size: 140%;
	color: red;

.sale-price-origin 
	text-decoration: line-through;

.add-shop 
	color: white;
	background-color: red;
	border-radius: 5px;
	padding: .5rem;
	white-space: nowrap;

footer 
	/**
	fixed是相对于浏览器窗口进行定位,跟absolute一样也是绝对定位
	但是它俩的参照物不同:
	fixed参考的是浏览器窗口
	absolute参考的是relative的祖先
	*/
	position: fixed;
	box-shadow: 0 0 .5rem gray;
	width: 100%;
	bottom:0px;

#shopCart  
	display: inline-block;
	width: 2rem;
	height: 2rem;
	padding: 1rem;

</style>
<template id="template">
<div class="goods-img">
	<!--
	<img style="background-image:url(' src ')"/>
	-->
	<img src=" src "/>
</div>
<div class="goods-desc">
<div class="goods-name"> name </div>
<div class="sale-volume">月销 saleVolume</div>
<div class="goods-buy">
	<div class="sale-price">
		<span class="sale-price-now">¥price</span>
		<span>/份&nbsp;</span>
		<span class="sale-price-origin">¥priceOrigin/份&nbsp;</span>
	</div>
	<div class="add-shop">加入购物车</div>
</div>
</div>
</template>
<script>
const data = 
	data:[
		name: "谷歌浏览器", src:"https://ss2.baidu.com/6ONYsjip0QIZ8tyhnq/it/u=3260362442,351141342&amp;fm=58" , saleVolume: 123, price: 20, priceOrigin: 999,
		name: "搜狗浏览器", src:"https://ss2.baidu.com/6ONYsjip0QIZ8tyhnq/it/u=3710305442,2088471281&amp;fm=58" , saleVolume: 1, price: 1, priceOrigin: 6,
		name: "火狐浏览器", src:"https://ss2.baidu.com/6ONYsjip0QIZ8tyhnq/it/u=3824766833,1967460780&fm=58&s=74F528722828EF3AC1BF94F50300C028&bpow=121&bpoh=75" , saleVolume: 992, price: 37, priceOrigin: 666,
		name: "简单搜索", src:"https://ss1.baidu.com/6ONXsjip0QIZ8tyhnq/it/u=2407325608,2146020119&amp;fm=58" , saleVolume: 500, price: 25, priceOrigin: 555,
		name: "UC浏览器", src:"https://ss1.baidu.com/6ONXsjip0QIZ8tyhnq/it/u=252893326,2138469974&amp;fm=58" , saleVolume: 33, price: 5, priceOrigin: 88,
		
	], delimiters: ["", ""]
;
String.prototype.trim = function() 
	//该方法不改变原始字符串,并且返回一个新的字符串
	return this.replace(/^\\s*|\\s*$/g, '');

function templateEngine(data, template, delimiters) 
	/*
	不加入g,则只返回第一个匹配,无论执行多少次均是如此,
	如果加入g,则第一次执行也返回第一个匹配,再执行返回第二个匹配,依次类推
	i,表示忽略大小写 ignore
	m,表明可以进行多行匹配
	
	\\\\s表示不可见字符
	\\\\S表示可见字符
	.等价于\\\\s|\\\\S
	
	最长匹配(贪婪匹配)和最短匹配(懒惰匹配,在长度指示符后面加?)
	*/
	const regStr = "(.+?)";
	//const regStr = "(\\\\s*\\\\S+?\\\\s*)";
	const reg = new RegExp(delimiters[0] + regStr + delimiters[1], "g");
	let str = template.innerHTML.replace(reg, function() 
		/*
		这里的RegExp是全局对象,RegExp.$1...$9是全局属性。
		每次执行正则表达式操作,都会覆盖掉之前的存储数据
		由于string.replace是先查找出所有之后,在一次性替换
		
		arguments的第一个参数是匹配模式的字符串。
		接下来的参数是与模式中的子表达式匹配的字符串,可以有 0 个或多个这样的参数。
		接下来的参数是一个整数,声明了匹配在 stringObject 中出现的位置。
		最后一个参数是 stringObject 本身。
		
		chrome中RegExp.$1无法获取到值,只能通过arguments来得到值
		firefox可以用RegExp获取子表达式的值
		*/
		return data[( RegExp.$1 || arguments[1]).trim()];
	);
	return str;

window.onload = ()=>
	const template = document.getElementById("template");
	const goodsList = document.getElementsByClassName("goods-list")[0];
	for(const d of data.data) 
		const li = document.createElement("li");
		li.innerHTML = templateEngine(d, template, data.delimiters);
		goodsList.appendChild(li);
	

</script>
</head>
<body>
<ul class="goods-list">
</ul>
<footer>
	<img id="shopCart" src="https://timgsa.baidu.com/timg?image&quality=80&size=b10000_10000&sec=1545113836&di=95ae09e0ada9cb41b10498ae63c15447&src=http://pic.90sjimg.com/design/00/69/49/81/58faca780920b.png">
</footer>
</body>
</html>

以上是关于JavaScript 自制可以替换属性的模板引擎(Template)的主要内容,如果未能解决你的问题,请参考以下文章

[自制模板引擎]添加指令

模板引擎

Javascript MVC 学习笔记 视图和模板

javascript与php模板引擎实现原理

161213Maven资源替换和Freemarker模板

Twitter typeahead.js:可以使用 Angular JS 作为模板引擎吗?如果不是,我该如何替换 Hogan/Mustache js 的“”?