javaScript之實戰 頁面篩選功能


 友情提示:gif圖太小,可以ctrl 加 +鍵 放大

 成品如下:

 

 開始搭建 html  和  css

 

html代碼如下:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <!-- 格式化css默認樣式 -->
    <link rel="stylesheet" href="./css/css-comment.css">
    <!-- 搭建好基本樣式 -->
    <link rel="stylesheet" href="./css/篩選小demo.css">
</head>

<body>
    <div class="wra">
        <div class="wraTop">
            <input type="text">
            <div class="sex">
                <span class="btn" id="m">Male</span>
                <span class="btn" id="f">Female</span>
                <span class="btn default" id="a">All</span>
            </div>
            <div class="age">
            </div>
        </div>
        <div class="wraBottom">
            <ul>
                <li>
                    <img src="./img/head.jpg">
                    <p class="name">王小明</p>
                    <span>18歲</span>
                    <p class="des">成績很好</p>
                </li>
                <li>
                    <img src="./img/head.jpg">
                    <p class="name">王小明</p>
                    <span>18歲</span>
                    <p class="des">成績很好</p>
                </li>
                <li>
                    <img src="./img/head.jpg">
                    <p class="name">王小明</p>
                    <span>18歲</span>
                    <p class="des">成績很好</p>
                </li>
                <li>
                    <img src="./img/head.jpg">
                    <p class="name">王小明</p>
                    <span>18歲</span>
                    <p class="des">成績很好</p>
                </li>
                <li>
                    <img src="./img/head.jpg">
                    <p class="name">王小明</p>
                    <span>18歲</span>
                    <p class="des">成績很好</p>
                </li>
            </ul>
        </div>
    </div>
</body>

</html>

css代碼如下:

.wra {
    width: 500px;
    margin: 100px  auto 0px; 
    border: 1px solid #d7d7d7;
    padding: 10px 15px;
    border-radius: 5px;
}

.wra .wraTop{
    margin-top: 10px;
    margin-bottom: 10px;
}
.wra .wraTop input{
    width: 240px;
    height: 20px;
    outline: none;
    border:1px solid #d7d7d7;
    padding-left: 10px;
    border-radius: 5px;
}

.wra .wraTop .sex{
   display:inline-block;
}

.wra .wraTop .btn{
    display: inline-block;
    height: 18px;
    margin-left: 10px;
    cursor:pointer;
    line-height:18px;
    padding: 1px 2px;
    border-radius: 2px;
}

.wra .wraTop .btn.default{
    color: #fff;
    background-color: rgb(77, 199, 247);
}

/* bottom */


.wra .wraBottom ul li{
    position: relative;
    margin-bottom:15px;
    border-bottom: 1px solid rgb(245, 242, 242);
    padding: 10px 0px 10px 50px;
}
.wra .wraBottom ul li img{
    position: absolute;
    top: 10px;
    left: 0px;
    width: 40px;
    height: 40px;
}

.wra .wraBottom ul li span{
    display: inline-block;
    margin: 5px 0;
}

.wra .wraBottom ul li .des{
    color: rgb(228, 95, 95);
    font-size: 10px;
}

搭建好的效果:

先把html ul 標簽里面的全部代碼刪除,再利用js代碼構建。

js 代碼如下

var arr = [ //模擬后台給的數據
    { name: "王小明", src: "./img/head.jpg", des: "成績很好", sex: "m", age: 18 },
    { name: "王大海", src: "./img/head.jpg", des: "長得帥", sex: "m", age: 19 },
    { name: "劉小紅", src: "./img/head.jpg", des: "莫名的喜感", sex: "f", age: 17 },
    { name: "孫小白", src: "./img/head.jpg", des: "一白遮三丑", sex: "f", age: 16 },
    { name: "劉小黑", src: "./img/head.jpg", des: "成績很好", sex: "m", age: 20 }
];
var wra = document.getElementsByClassName("wra")[0];
var wb = wra.getElementsByClassName("wraBottom")[0];
var oUl = wb.getElementsByTagName("ul")[0];
var sex = document.getElementsByClassName('sex')[0];
var sexbtn = sex.getElementsByClassName("btn");
var inp = wra.getElementsByTagName("input")[0];

//創建全局默認值,記錄每一次事件觸發的數值
var state = {
    text: '',
    sex: 'a'
}



// 渲染頁面
function renderPage(data) {
    oUl.innerHTML = "";
    data.forEach(function (ele, index, self) {
        //遍歷數組里面的東西,取其中數據構建html結構,
        oUl.innerHTML += '<li><img src=' + ele.src + '><p class="name">' + ele.name + '</p><span>' + ele.age + '歲</span><p class="des">' + ele.des + '</p></li>';
    });
}
renderPage(arr);



//綁定性別點擊事件
var lastDefault = sexbtn[2]; //默認性別選項All 
for(var i = 0; i < sexbtn.length; i++){
    (function(j){
        sexbtn[j].onclick = function(){
            sexbtn[j].className = "btn default";//點擊時,給點擊的按鈕添加 css樣式(default)
            lastDefault.className = "btn";// 賦給樣式后,取消上一個btn的樣式
            lastDefault = sexbtn[j];//賦給樣式后,此次點擊的btn 就成了過去

            state.sex = sexbtn[j].id;
            var newArr = screenSex(arr, state.sex); //篩選性別執行后返回新數組
            renderPage( screenInput(newArr, state.text));//利用新數組再次篩選搜索框,篩選后渲染頁面
        }
    })(i)
}
// 篩選性別函數
function screenSex(data, sex) {
    if (sex == "a") { //判斷輸入的值是否為默認值a,如果是,不用篩選,直接返回原數組
        return data;
    } else {
        return data.filter(function (ele, index, self) {//利用數組方法filter過濾,不懂filter方法,請看本人另外筆記filter方法
            return sex == ele.sex; 
            //第一遍循環,查看 數組第一個數據里面的 sex 是否等於 傳進來的sex  如果是,返回這條數據到新數組
            //{ name: "王小明", src: "./img/head.jpg", des: "成績很好", sex: "m", age: 18 }  
        })
    }
}

//觸發input事件
inp.oninput = function(){
    state.text = this.value;//記錄當前輸入的字
    var newArr = screenInput(arr, state.text);//篩選搜索框輸入的值,執行后返回新數組
    renderPage( screenSex(newArr, state.sex));//利用新數組再次篩選性別,篩選后渲染頁面
    
}
//篩選搜索框函數 
function screenInput(data, value){
    if(!value){//判斷輸入的值是否為默認值'',如果是,不用過濾,直接返回原數組
        return data;
    }else{
      return data.filter(function(ele, index, self){
           return ele.name.indexOf(value) >= 0; 
            //字符串方法,indexOf 查看value這個字符串,是否存在於ele.name中,如果存在返回大於0的索引(true)
            //如果不存在,返回-1,(false)
            //如果返回(true),返回這條數據到新數組中
       })
    }
}

此功能已經完成,如果除了篩選性別和篩選輸入之外有新的行為,代碼會越來越冗余,加入設計思想,管理行為,

全局默認值是裸露的,誰都可以修改它。封裝全局默認值。

 

首先,創建空文件夾專門放行為,抽出行為(篩選搜索框函數 和 篩選性別的函數),創建單獨文件。

 

 

創建store.js文件,用來管理全局默認值,添加以下代碼。

 

 

現在編輯store.js文件 的dispatch函數,咋們希望的是,觸發事件的時候,獲取觸發的那個數值,傳入dispatch函數就可以修改全局的默認值(記得引入文件哦)

 

 

 接下來合並我們的篩選函數,創建combineFilter.js文件

//此方法用於執行執行screenInput 和 screenSex函數
function combineFilter(comfig){
    return function (data){ //這里data的值,是通過調用lastFilterArr(這里傳入的)

        for(var i in comfig){
            data = comfig[i](data, store.getState(i))//要拿到input觸發事件的value,只能通過store.getState方法取,此時的i為text

            //第一圈循環相當於 取出screenInput函數傳入數據執行(data, store.getState(i))執行后的結果data接收
            
            //data 接收screenInput過濾后的新數組,等待第二次循環
            //第二次循環 輪到screenSex 函數, 此時 傳入的data是screenInput過濾好后的數組,這樣就達到了 雙層過濾;
        }
        return data;
    }
}

var lastFilterArr = combineFilter({
    text: screenInput, //這兩個函數,是我們抽出來的行為,
    sex: screenSex
     //這里傳入的值  combineFilter(comfig)  接收
})

 

最后一步,實現我們store.subscribe方法   用我們上一步實現好的 combineFilter.js文件里面的  lastFilterArr() 方法

lastFilterArr(arr) 放入我們要過濾的數組, 通過 screenInput   screenSex 這兩個函數循環過濾,過濾后 用renderPage 渲染頁面,把這些放入

store.subscribe方法中,當我們觸發事件的時候,通過dispatch修改 值的時候, 自動觸發subscribe方法

 

 

 最后 加上防抖功能

function debounce(handler, delay) {
    var timer = null;
    return function () {
        var _self = this,
            _arg = arguments;
      clearTimeout(timer);
        timer = setTimeout(function () {
            handler.apply(_self, _arg);
        }, delay)
    }
}

 歡迎各位大佬們指出問題,謝謝你的查看。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM