一个小众的前端渲染工具

291 阅读4分钟

tempo 2.0

第一步、引入本地tempo.js文件和jquery.js文件

<script src="./js/tempo.js"></script>
<script src="./js/jquery-1.5.1.min.js"></script>

第二步、在script标签里准备好一个(json对象数据)

var data = [
{'name':{'first':'Leonard','last':'Marx'},'nickname':'Chico','born':'March 21, 1887','actor': true,'solo_endeavours':[{'title':'Papa Romani'}]},
{'name':{'first':'Adolph','last':'Marx'},'nickname':'Harpo','born':'November 23, 1888','actor':true,'solo_endeavours':[{'title':'Too Many Kisses',
'rating':'favourite'},{'title':'Stage Door Canteen'}]},
{'name':{'first':'Julius Henry','last':'Marx'},'nickname':'Groucho','born': 'October 2, 1890','actor':true,'solo_endeavours':[{'title':'Copacabana'},
{'title':'Mr. Music','rating':'favourite'},{'title':'Double Dynamite'}]},
{'name':{'first':'Milton','last':'Marx'},'nickname':'Gummo','born':'October 23, 1892'},
{'name':{'first':'Herbert','last':'Marx'},'nickname':'Zeppo','born':'February 25, 1901','actor':true,'solo_endeavours':[{'title':'A Kiss in the Dark'}]}
];

第三步、Tempo.prepare('container').render(data)

prepare(这里指向得是页面元素得id).render(这里可以理解为指向数据源)

Tempo.prepare() 函数会返回一个准备好渲染的模板实例。JSON 数据可用后,运行 render(data) 函数将数据添加到页面

//原生js方法
window.onload = function () {
        var template = Tempo.prepare('container').render(data);
}
//jquery方法
$(function () {
        var template = Tempo.prepare('container').render(data);
})

第四步、在body里创建一个标签,通过prepare里面得id来把数据渲染到body里

<body>
    <ul id="container">
        <li data-template>{{name.first}}--------------{{nickname}}</li>
    </ul>
</body>

注:Tempo 是将信息编码为 JSON 并根据 HTML 模板呈现在页面上

额。。。。。整体结构得话大概这个样子

<!DOCTYPE html>
<html lang="en"><head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="./js/tempo.js"></script>
    <script src="./js/jquery-1.5.1.min.js"></script>
</head><body>
    <ul id="container">
        <li data-template>{{name.first}}--------------{{nickname}}</li>
    </ul>
</body>
<script>
    var data = [
{'name':{'first':'Leonard','last':'Marx'},'nickname':'Chico','born':'March 21, 1887','actor': true,'solo_endeavours':[{'title':'Papa Romani'}]},
{'name':{'first':'Adolph','last':'Marx'},'nickname':'Harpo','born':'November 23, 1888','actor':true,'solo_endeavours':[{'title':'Too Many Kisses',
'rating':'favourite'},{'title':'Stage Door Canteen'}]},
{'name':{'first':'Julius Henry','last':'Marx'},'nickname':'Groucho','born': 'October 2, 1890','actor':true,'solo_endeavours':[{'title':'Copacabana'},
{'title':'Mr. Music','rating':'favourite'},{'title':'Double Dynamite'}]},
{'name':{'first':'Milton','last':'Marx'},'nickname':'Gummo','born':'October 23, 1892'},
{'name':{'first':'Herbert','last':'Marx'},'nickname':'Zeppo','born':'February 25, 1901','actor':true,'solo_endeavours':[{'title':'A Kiss in the Dark'}]}
];
​
    // window.onload = function () {
    //     var template = Tempo.prepare('container').render(data);
    // }
    $(function () {
        var template = Tempo.prepare('container').render(data);
    })
</script></html>

append()

append()方法我的理解是,如果数据源相同的话会把要渲染的数据重新渲染一边在'container'id的子标签里,类似与复制粘贴,如果渲染不同数据源的数据,名字一样会把前面的数据覆盖

var template = Tempo.prepare('container').render(data).append(data);

prepend()

prepend()方法和append()差不多,不过这个是会把数据渲染在render()渲染过的数据前面。同样如果不同数据源的话还是会覆盖掉

var template = Tempo.prepare('container').render(data).prepend(data);

clear()

这个比较好理解,就是清空数据

var template = Tempo.prepare('container').render(data).clear();

into()

into()可以理解为多数据源情况下,可以使用这个方法来分开使用,使用的时候注意分别放在不同的id容器下,不然会把前面的覆盖掉,依然数据源里面要渲染的数据名字不能一样

//省略为jquery方法
$(function () {
        var template = Tempo.prepare('container').render(data);
        template.into('box').render(data1)
})

关于出现在标签属性中的data-template

任何具有该属性的标签data-template都将被视为模板。为了合规,还支持完整(非最小化)表格:data-template="data-template" 类似于vue里的template

如果 JSON 数据表示一个数组数组(不能被字段/成员名称引用),例如:

var data = [ ['Leonard','Marx'], ['Adolph','Marx'], ['Julius Henry','Marx'], ['Milton','Marx'], ['Herbert','Marx'] ];

渲染在页面得时候可以使用下标规律的数组方式来渲染

<ol id="container">
    <li data-template>{{[0]}} {{[1]}}</li>
</ol>

如果 JSON 数据表示一个字符串数组,

var data = [ 'Leonard Marx', 'Adolph Marx', 'Julius Henry Marx', 'Milton Marx', 'Herbert Marx' ];

您可以引用正在迭代的对象{{.}}

<ol id="container">
        <li data-template>{{.}}</li>
</ol>

在使用tempo得时候要注意,HTML标签得嵌套关系,循环渲染谁就把data-template放在谁上面

例如:

<!DOCTYPE html>
<html lang="en"><head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="./js/jquery-1.5.1.min.js"></script>
    <script src="./js/tempo.js"></script>
    <script src="./js/tempo.min.js"></script>
</head><body>
    <ul id="list">
        <li data-template style="display: none;">{{c1}}</li>
    </ul>
​
    <script>
        var datad;
        function content() {
            var data = {
                "code": "1",
                "msg": "ok",
                "data": [
                    {
                        "c1": "first",
                        "c2": "2222"
                    },
                    {
                        "c1": "first",
                        "c2": "2222"
                    }
                ]
            }
            datad = data.data;
​
        }
        $(function () {
            content()
            var template = Tempo.prepare('list').render(datad)
        })
    </script>
</body></html>

删除列表,先用tempo的特性动态拿到json里的id,在html标签行内写一个onclick事件,通过onclick事件来获取id

<body>
    <ul id="message">
        <li data-template id="{{id}}">
            <!-- <img src="" alt="" data-src="{{path}}"> -->
            <h3>{{name}}</h3>
            <p>{{sex}}</p>
            <button onclick="del('{{id}}')">del</button>
        </li>
    </ul>
​
    <script>
        var point;
        function content() {
            var data = {
                "code": "1",
                "msg": "ok",
                "data": [
                    {
                        "id": "1",
                        "name": "zhangsan",
                        "sex": "boy",
                        "path": "./img/1.png"
                    },
                    {
                        "id": "2",
                        "name": "lisi",
                        "sex": "boy",
                        "path": "./img/1.png"
                    }
                ]
            }
            point = data.data;
            console.log(point.path);
        }
        $(function () {
            content();
            var template = Tempo.prepare("message").render(point)
        })
        // 移除
        function del(del) {
            $('#' + del).remove()
        }
    </script>
</body></html>

无限滚动

实现无限分页的过程大致如下:

1 视窗滚动到底部;

2 触发加载,添加到现有内容的后面。

因此,可能会出现两种情况:

1 当页面的内容很少,没有出现滚动条;触发加载页面事件,直到加载到满足条件时停止加载;

2 当页面的内容很多,出现了滚动条

首先要把用tempo渲染出来得数据标签,复制一份放在菜单上面,

<%--无限滚动--%>
<div class="wzlb004" id="ulContentList1" style="display: none">
    <div class="wzlb007" data-template style="display: none">
        <div class="d-paragra-logo d-dangwei-logo">
            <img src="../pro/img/tb132.png">
        </div>
        <div class="wzlb002">
            <p>
                {{c1}}
            </p>
        </div>
    </div>
</div>

然后定义变量

//tempo渲染数据
var template;
//指向json数据
var mh166DataJ;
//模板解析地址参数,将地址栏参数变更为json
var mh166Param;
//指向json数据中key为total的变量
var mh166TotalCount;

定义一个json的数据结构,这个可以多复制几条,为了节省空间暂时放了三条

function mh166GetJ() {
        var data = {
    "code": "Cabbage",
    "msg": "ok",
    "data": [
        {
            "c1": "回首过去一年"
        },
        {
            "c1": "回首过去一年"
        },
        {
            "c1": "回首过去一年"
        }
        
    ]
}
        mh166DataJ = data.data;
        mh166TotalCount = data.total;
    }

然后就开始写方法,是一个早期比较古老的方法,就是通过依赖监听scroll事件然后计算各种.scrollTop().offset().top等等。

这个方法比较枯燥。而且:

  • scroll事件会频繁触发,因此我们还需要手动节流。
  • 滚动元素内有大量DOM,容易造成卡顿。
        //无限滚动
        mh166Param["page"] = 1;
        mh166Param["pageSize"] = 12;
        //定义一个滚动,使用tempo的方法
        var scrollTempo = Tempo.prepare("ulContentList1");
        //关于scrollLoading()是已经封装好的方法,给她指定参数为ulContentList也就是tempo的容器id
        scrollLoading("ulContentList",function(){
            var mh166TotalPage = Math.ceil(mh166TotalCount / 12);
            if(mh166Param.page < mh166TotalPage){
                console.log(mh166TotalCount)
                //请求数据
                mh166Param.page = parseInt(mh166Param.page) + 1;
                mh166GetJ(decodeURIComponent("${du}"), mh166Param);
                scrollTempo.render(mh166DataJ);
                var html = $("#ulContentList1").html();
                $("#ulContentList").append(html);
            }
        })

搜索功能

首先在行内写入onclick事件来触发按钮

<div class="d-spell">
            <!--搜索框-->
            <div class="kuan" style="font-size: 2.2vh;"><input name="" type="text" /></div>
            <a href="#" style="font-size: 2.2vh;" onclick="searchClear(this)">清空</a>
            <a href="#" style="font-size: 2.2vh;" onclick="searchBtn(this)">搜索</a>
            <a class="a-active" href="#" style=font-size:2.2vh;" onclick="searchAllBtn(this)">全部</a>
            <a href="#" value="a" onclick="letter(this)">A</a>
            <a href="#" onclick="letter(this)">B</a>
            <a href="#" onclick="letter(this)">C</a>
            <a href="#" onclick="letter(this)">D</a>
            <a href="#" onclick="letter(this)">E</a>
            <a href="#" onclick="letter(this)">F</a>
            <a href="#" onclick="letter(this)">G</a>
            <a href="#" onclick="letter(this)">H</a>
            <a href="#" onclick="letter(this)">J</a>
            <a href="#" onclick="letter(this)">K</a>
            <a href="#" onclick="letter(this)">L</a>
            <a href="#" onclick="letter(this)">M</a>
            <a href="#" onclick="letter(this)">N</a>
            <a href="#" onclick="letter(this)">O</a>
            <a href="#" onclick="letter(this)">P</a>
            <a href="#" onclick="letter(this)">Q</a>
            <a href="#" onclick="letter(this)">R</a>
            <a href="#" onclick="letter(this)">S</a>
            <a href="#" onclick="letter(this)">T</a>
            <a href="#" onclick="letter(this)">W</a>
            <a href="#" onclick="letter(this)">X</a>
            <a href="#" onclick="letter(this)">Y</a>
            <a href="#" onclick="letter(this)">Z</a>
        </div>

第一步先写搜索按钮

//搜索
    function searchBtn(obj) {
        var tmp = obj;
        //把input框元素里的值赋给firstLetter变量
        firstLetter = $(".kuan input").val();
        console.log(firstLetter);
        $(tmp).siblings().removeClass("a-active");
        $(tmp).addClass("a-active");
        //根据首字母和页面参数加载
        mh1zxGetJ(decodeURIComponent("${du}"), mh1zxParam);
        mh1zxListTempo.render(mh1zxResultData);
    }

第二步是全部按钮

 //全部按钮
    function searchAllBtn(obj) {
        var tmp = obj;
        //定义首字母为空字符串
        firstLetter = "";
        //获取文本框内value值
        $(".kuan input").val();
        $(tmp).siblings().removeClass("a-active");
        $(tmp).addClass("a-active");
        //根据首字母和页面参数加载
        mh1zxGetJ(decodeURIComponent("${du}"), mh1zxParam);
        mh1zxListTempo.render(mh1zxResultData);
    }

第三步清除按钮

//清除搜索框
    function searchClear(obj){
        //更改this指向为元素本身
        var tmp = obj;
        //给input文本框清空内容
        $(".kuan input").val("");
        //清除本身外的a-active样式
        $(tmp).siblings().removeClass("a-active");
        //给元素再添加样式
        $(tmp).addClass("a-active");
    }

第四步把字母按钮,点击后填到input搜索框内

//a标签字母添加到搜索框
    function letter(obj) {
        //判断文本框内是否为空
        if ($(".kuan input").val() == "") {
            $(".kuan input").val($(".kuan input").val() + $(obj).text());
        }else{
            //如果不为空则清空后再填充按钮字母
            $(".kuan input").val("");
            $(".kuan input").val($(".kuan input").val() + $(obj).text());
        }
    }

\