基于模版引擎实现-淘宝搜索案例

51 篇文章 2 订阅
35 篇文章 3 订阅

通过这个案例,我们了解一些知识,比如模版引擎、防抖和节流 

先来看看效果图:

功能:当用户输入关键字后,对应的数组建议罗列出来 

先来看看html框架

   <div class="container">
        <!-- Logo -->
        <img src="./images/taobao_logo.png" alt="" class="logo" />

        <div class="box">
            <!-- tab 栏 -->
            <div class="tabs">
                <div class="tab-active">宝贝</div>
                <div>店铺</div>
            </div>
            <!-- 搜索区域(搜索框和搜索按钮) -->
            <div class="search-box">
                <input id="ipt" type="text" class="ipt" placeholder="请输入要搜索的内容" /><button class="btnSearch">
                    搜索
                </button>
            </div>
            <!-- 搜索建议列表 -->
            <div id="suggest-list"></div>
        </div>
    </div>

首先为输入框绑定keyup事件

获取用户输入的内容 $(this).val().trim(),对文本框里面的内容进行判断,如果文本框里面没有内容 就把建议列表清空并隐藏

          $('#ipt').on('keyup', function () {
                var keywords = $(this).val().trim()
                if (keywords.length <= 0) {
                    return $('#suggest-list').empty().hide()
                }

                getSuggestList(keywords)
            })

 接下来封装一个getSuggestList函数,发送一个JSONP请求,获取到对应的建议列表 有个q属性 kw就是我们输入的关键字

          function getSuggestList(kw) {
                $.ajax({
                    url: 'https://suggest.taobao.com/sug?q=' + kw,
                    dataType: 'jsonp',
                    success: function (res) {
                        console.log(res)
                    }
                })
            }

将每一条建议渲染到页面中【定义模版结构】在定义模版引擎前,先给大家介绍哈什么是模版引擎

模版引擎 

概念:模版引擎,顾名思义,它可以根据程序员指定的模版结构和数据,自动生成一个完整的html页面

执行过程:程序员提供数据和模版结构传给模版引擎 模版引擎在内部将两者做成一个完成的html结构

好处:

  • 减少了字符串拼接
  • 代码更加清晰
  • 使代码更易于阅读和维护

在本案例中,我使用的模版引擎是art-template 

使用步骤:

  1. 导入 art-template
  2. 定义数据
  3. 定义模版
  4. 调用template函数【有两个参数 数据和模版】
  5. 渲染html结构

 art-template标准语法

 art-template提供{{}}这种语法格式,在{{}}内可以进行变量输出,或循环数组等操作,这种{{}}语法在art-template中被称为标准语法

  • 标准语法-输出

在{{}}语法中,可以进行变量的输出、对象属性的输出、三元表达式输出、逻辑或输出、加减乘除等表达式输出

比如---------{{value}} || {{obj.key}} || {{obj['key']}} ||  {{a?b:c}}  ||  {{a || b}} ||  {{a+b}}

  • 标准语法-原文输出

语法:{{ @value}}  

如果要输出的value值中,包含了html标签结构,则需要使用原文输出语法,才能保证html标签被正常渲染

  • 标准语法-条件输出

如果要实现条件输出,则可以在{{}}中使用if...else if .../if的方式,进行按需输出

{{if value}} 按需输出内容 {{/if}}
{if v1}} 按需输出的内容 {{else if v2}} 按需输出的内容{{/if}}

  • 标准语法-循环输出

语法:
{{each arr}}
    {{$index}} {{$value}}
{{/each}}

如果要实现循环输出,则可以在{{}} 内,通过each语法循环数组,当前循环的索引使用$index进行访问

  • 标准语法-过滤函数

{{value} | filterName}} 左边是一个值,右边是一个处理函数,返回一个新值 相当于调用过滤器函数

定义过滤器的基本语法:
template.defaults.imports.filterName = function(value){ return处理的结果 }

再回到案例当中,现在需要实现将建议内容渲染到页面中 

使用模版引擎里面的循环输出,去循环result里面的每一项,没循环一次就创建一个div,数据是 {{$value[0]}} 每一个数组键的第一个值

<!-- 搜索建议列表 -->
<div id="suggest-list"></div>

//模版结构 循环服务器返回的数据 去循环result里面的每一项,
<script type="text/html" id="tpl-suggestList">
     {{each result}}
       <div class="suggest-item">{{$value[0]}}</div>
     {{/each}}
</script>

定义渲染模版结构的函数

先判断里面有没有要渲染的数据,没有的话讲建议列表 清空并隐藏,

如果有 

                var htmlStr = template('tpl-suggestList', res)   调用模版引擎函数
                $('#suggest-list').html(htmlStr).show()    将处理好的数据渲染到建议列表,并将此显示

          // 渲染UI结构
            function renderSuggestList(res) {
                if (res.result.length <= 0) {
                    return $('#suggest-list').empty().hide()
                }
                var htmlStr = template('tpl-suggestList', res)
                $('#suggest-list').html(htmlStr).show()

            }

细节问题一:当用户输入内容的时候,每输入一个字母,就会服务器就会请求一次数据,请求的次数很多

解决方案:通过防抖,有效减少请求的次数,节约请求资源

实现输出框的防抖

var  timer = null      //1、防抖动的timer

function debounceSearch(keywords) {   //2、定义防抖的函数

    timer = setTimerout(function() {

    //   发起JSONP请求

    getSuggestList(keywords)

},500)

$("#ipt").on('keyup',function(){ // 3、在触发keyup事件时,立即清空timer

     clearTimeout(timer)

     ....

     debounceSearch(keywords)

 )

在500毫秒以内,清除定时器 ,服务器就不会发起请求

细节问题二:当我们输入 apple 后 在输入一个mac,如果我们值保留appla的搜索的时候,服务器又会重新请求一次。 重复请求了 

 解决方案:将我们之前的搜索建议进行缓存,再发起相同的请求的时候,就去寻找缓存里面的建议,提高了搜索效率

// 定义全局缓存对象
 var cacheObj = {}
// 1. 获取到用户输入的内容,当做键
 var k = $('#ipt').val().trim()
// 2. 需要将数据作为值,进行缓存
  cacheObj[k] = res

优先从缓存中取数据,在发起请求之前,先判断缓存里有没有这个键

在keyup事件后面进行一次判断

 //先判断缓存中是否有数据
  if (cacheObj[keywords]) {
      return renderSuggestList(cacheObj[keywords])
 }
  debounceSearch(keywords)

js完整代码

<script>
        $(function () {
            // 1. 定义延时器的Id
            var timer = null
            // 定义全局缓存对象
            var cacheObj = {}

            // 2. 定义防抖的函数
            function debounceSearch(kw) {
                timer = setTimeout(function () {
                    getSuggestList(kw)
                }, 500)
            }

            // 为输入框绑定 keyup 事件
            $('#ipt').on('keyup', function () {
                // 3. 清空 timer
                clearTimeout(timer)
                var keywords = $(this).val().trim()
                if (keywords.length <= 0) {
                    return $('#suggest-list').empty().hide()
                }

                // 先判断缓存中是否有数据
                if (cacheObj[keywords]) {
                    return renderSuggestList(cacheObj[keywords])
                }
                debounceSearch(keywords)
            })

            function getSuggestList(kw) {
                $.ajax({
                    url: 'https://suggest.taobao.com/sug?q=' + kw,
                    dataType: 'jsonp',
                    success: function (res) {
                        renderSuggestList(res)
                    }
                })
            }

            // 渲染UI结构
            function renderSuggestList(res) {
                if (res.result.length <= 0) {
                    return $('#suggest-list').empty().hide()
                }
                var htmlStr = template('tpl-suggestList', res)
                $('#suggest-list').html(htmlStr).show()

                // 1. 获取到用户输入的内容,当做键
                var k = $('#ipt').val().trim()
                // 2. 需要将数据作为值,进行缓存
                cacheObj[k] = res
            }
        })
    </script>

 

  • 11
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 13
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

奶茶丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值