• 原生JavaScript实战之搜索框筛选功能


    成品图如下所示:

    先搭建HTML结构:

     1     <div class="wrapper">
     2         <div class="sWrapper">
     3             <input type="text" class="sText">
     4             <span class="btn" sex="m">Male</span>
     5             <span class="btn" sex="f">Female</span>
     6             <span class="btn active" sex="a">All</span>
     7         </div>
     8         <div class="flWrapper">
     9             <ul>
    10                 
    35             </ul> 
    36         </div>
    37     </div>

    CSS样式:

     1 *{
     2             margin:0px;
     3             padding: 0px;
     4             list-style: none;
     5         }
     6         .wrapper{
     7             400px;
     8             padding:10px 15px;
     9             border: 1px solid #ccc;
    10             margin:100px auto 0px;
    11             border-radius: 6px;
    12         }
    13         img{
    14              50px;
    15             height: 50px;
    16         }
    17         .wrapper .sWrapper{
    18             margin-bottom: 20px;
    19         }
    20         .wrapper .sWrapper input{
    21              220px;
    22             height: 25px;
    23             padding-left:10px; 
    24             outline: none;
    25             border-radius:4px;
    26             border:1px solid #777;
    27         }
    28         .wrapper .sWrapper .btn{
    29             cursor: pointer;
    30             color: #3c8dff;
    31             padding: 0px 5px;
    32             border-radius: 4px;
    33         }
    34         .wrapper .sWrapper .btn.active{
    35             color:#fff;
    36             background: #3c8dff;
    37         }
    38         .wrapper .flWrapper ul li {
    39             position: relative;
    40             padding-left: 60px;
    41             padding-top: 10px;
    42             padding-bottom: 10px;
    43             border-bottom:1px solid #999;
    44         }
    45         .wrapper .flWrapper ul li img {
    46             position: absolute;
    47             left: 0px;
    48             top:10px;
    49         }
    50         .wrapper .flWrapper ul li .name {
    51             margin-bottom: 10px;
    52         }
    53         .wrapper .flWrapper ul .li .des {
    54             font-size: 12px;
    55             color:#666;
    56         }

    需要创建的文件如下所:

    开始写JS代码:

    index.js

     1 //模拟后端传过来的数据表单
     2 var personArr = [
     3     { name: '大钢铁', src: '../ing/gnag.PNG', des: 'I am gang', sex: 'm', age: 18 },
     4     { name: '小女巫', src: '../ing/fei.PNG', des: 'I am fei', sex: 'f', age: 19 },
     5     { name: '大绿巨', src: '../ing/lv.PNG', des: 'I am lv', sex: 'm', age: 20 },
     6     { name: '大寡妇', src: '../ing/hei.PNG', des: 'I am black wife', sex: 'f', age: 23 },
     7     { name: '小队长', src: '../ing/mei.PNG', des: 'I am USA', sex: 'm', age: 24 },
     8 ];
     9 
    10 
    11 
    12 // 初始变量
    13 var oUl = document.getElementsByTagName('ul')[0];
    14 var oInput = document.getElementsByTagName('input')[0];
    15 
    16 
    17 
    18 store.subscribe(function () {
    19     RenderPage(lastFilterArr(personArr));
    20 });
    21 
    22 
    23 // 数据渲染页面 
    24 function RenderPage(data) {
    25     //遍历数组长度添加
    26     var htmlStr = ''; //设定一个空字符串接收数据
    27     oUl.innerHTML = ''; //
    28     data.forEach(function (ele, index, self) {
    29         htmlStr = htmlStr + '<li><img src="' + ele.src + '"><img/><p class="name">' + ele.name + '</p><p class="dse">' + ele.des + '</p></li>';
    30         //遍历出后端里面的数据
    31     });
    32     oUl.innerHTML = htmlStr; //把数据以HTML形式付给页面
    33 }
    34 RenderPage(personArr);// 执行渲染函数
    35 
    36 
    37 
    38 //添加行为
    39 oInput.oninput = debounce(function () { //输入触发过滤
    40     store.dispatch({ type: 'text', value: this.value });
    41     //传到渲染页面的函数中,重新绘制页面
    42 }, 1000);//最后再加上防抖功能,也就是相当于套上一个定时器,输入文本1秒后再执行搜索
    43 
    44 
    45 
    46 
    47 
    48 //btn style
    49 var oBtnArr = [].slice.call(document.getElementsByClassName('btn'), 0);
    50 //把btn类数组转为数组
    51 
    52 var lastActiveBtn = oBtnArr[2];
    53 
    54 oBtnArr.forEach(function (ele, index, self) {
    55     ele.onclick = function () {
    56         changeActive(this);
    57         RenderPage(filterArrBySex(personArr, this.getAttribute('sex')));
    58         store.dispatch({ type: 'sex', value: this.getAttribute('sex') });
    59         //渲染过滤后的性别
    60     }
    61 });
    62 
    63 //点击按钮切换样式
    64 function changeActive(curActiveBtn) {
    65     curActiveBtn.className = 'btn active';
    66     lastActiveBtn.className = 'btn';
    67     lastActiveBtn = curActiveBtn;
    68 }

     写入过滤函数

    文本过滤:

    filterArrByText.js
     1 // text -- 根据文本来过滤
     2 function filterArrByText(data, text){
     3     if(!text){ //非文本则返回数据表单
     4         return data;
     5     }else{  //否则进入一下进行过滤
     6         return data.filter(function(ele, index){
     7             return ele.name.indexOf(text) != -1;
     8             //返回indexOf文本不等于-1的文本
     9             //如果输入的文本不在数据表单名字里面indexOf则会返回-1
    10         });
    11     }
    12 }

    性别过滤: 

    filterArrBySex.js
     1  // sex -- 根据性别过滤
     2  function filterArrBySex (data, sex){
     3     if(sex == 'a'){
     4         return data;
     5         //如果传入的是a,就返回a
     6     }else{
     7         return data.filter(function (ele, index, self){
     8             return ele.sex == sex;
     9             //如果sex等于传入的sex,就返回相应的sex
    10         })
    11     }
    12 }

     合并过滤函数

    combineFilter.js
     1 function combineFilter (config){
     2     return function (data){
     3         for(var prop in config){ //循环过滤这两个函数
     4             //依次过滤这两个函数,先过滤文本数据后返回给data
     5             //data拿到的过滤一次后的数据再次过滤一次把性别再过滤一次
     6             data = config[prop](data, store.getState(prop));
     7         }
     8         return data; //最后过滤完返回出来
     9     }
    10 }
    11 //接收过滤函数传到combineFilter这个文件,接着合并等于lastFilterArr
    12 var lastFilterArr = combineFilter({
    13     text: filterArrByText,
    14     sex: filterArrBySex
    15 })

    再加入设计模式

    (变量不裸露方便管理)

    createStore.js
     1 function createStore (initialState) {
     2     var stata = initialState || {};
     3     var list = [];
     4     //获取
     5     function getState (type) {
     6         return stata[type];
     7     }
     8     //处理
     9     function dispatch (action) {
    10         stata[action.type] = action.value;
    11         //调用之前订阅过的函数
    12         list.forEach(function(ele){
    13             ele();
    14         })
    15     }
    16     //订阅
    17     function subscribe (func) {
    18         list.push(func);
    19         
    20     }
    21     return {
    22         getState:getState,
    23         dispatch:dispatch,
    24         subscribe:subscribe
    25     }
    26 }
    27 
    28 var store = createStore({text: '', sex: 'a'});

    最后再加上防抖功能

    debounce.js
     1 //防抖功能,就是搜索框输入文字1秒后再进行搜索
     2 function debounce (handler, delay){
     3     var timer = null;
     4     return function (e) {
     5         var _self = this, _arg = arguments;
     6         clearTimeout(timer);
     7         timer = setTimeout(function () {
     8             handler.apply(_self, _arg);
     9         },delay);
    10     }
    11 }

     谢谢观看,有大佬经过请指出意见

  • 相关阅读:
    vue-cli element axios sass 安装
    Rem-- ui图与适配手机的px换算
    REM
    Canvas画半圆扇形统计图
    在vue中安装SASS
    在vue中引用.SCSS的公用文件
    Echart--折线图手柄触发事件
    vue 脚手架webpack打包后,解决能看到vue源码的问题
    js 函数 /变量/ 以及函数中形参的预解析的顺序
    【算法日记】4.递归和快速排序
  • 原文地址:https://www.cnblogs.com/yangpeixian/p/10837378.html
Copyright © 2020-2023  润新知