复合筛选框

需求:

  • 根据按钮筛选出同一性别的数据。
  • 根据输入框输入的名字筛选出具有输入框里字符的数据。
  • 根据年龄将数据进行排序。

更新:

  • 没有复选效果(点击性别,再输入名字时会重新筛选)
  • 增加年龄筛选适应各种情况。
    有空再上传

项目样式图

你们喜欢的英雄

该项目主要练习操作数组的一些方法和不能改变原数据的编程思想。

HTML代码

<div class="wrapper">
        <input type="text" >
        <button class="active">All</button>
        <button>Female</button>
        <button>Male</button>
        <button>age</button>
        <ul>
            <!-- <li class="del">
                <img src="./1.PNG" alt="">
                <p class="name">王某某</p>
                <p class="age">18</p>
                <p class="say">迎娶白富美,走上人生巅峰</p>
            </li>
            <li class="del">
                <img src="./1.PNG" alt="">
                <p class="name">平头哥</p>
                <p class="age">18</p>
                <p class="say">不服就是干!!</p>
            </li> -->
        </ul>
    </div>

写插入数据的CSS样式时可以自己写一些HTML结构,写完CSS注释掉。后面渲染插入的数据时用JS自动网页面添加HTML。

CSS代码

* {
    padding: 0px;
    margin: 0px;
    list-style: none;
}
.wrapper{
    position: absolute;
    width: 600px;
    border: 1px solid rgb(230, 219, 219);
    border-radius: 10px;
    left: 50%;
    margin-left: -250px;
    padding: 10px;
}
.wrapper input{
    position: relative;
    height: 25px;
    width: 280px;
    padding-left: 10px;
    border: 1px solid blue;
    border-radius: 5px;
    outline: none;
}
.wrapper button{
    float: right;
    height: 25px;
    width: 60px;
    border-radius: 10px;
    background-color: #ffff;
    outline: none;
    border: none;
    margin-left: 15px;
    font-size: 17px;
    font-weight: 600;
    line-height: 25px;
    text-align: center;
    color: blue;
}
.wrapper button.active{
    color: #fff;
    background-color: blue;
}
.wrapper ul li{
    position: relative;
    height: 70px;
    width: 600px;
    margin-top: 5px;
    border: 1px solid #fff;
    border-bottom: 2px solid rgb(239, 228, 228);
}
.wrapper ul li img{
    display: block;
    height: 40px;
    width: 40px;
    margin-top: 10px;
    /*margin-left: 5px;*/

}
.wrapper ul li .name{
    position: absolute;
    height: 20px;
    line-height: 20px;
    padding: 5px;
    font-size: 20px;
    font-weight: 800;
    left: 45px;
    top: 5px;

}
.wrapper ul li .age{
    position: absolute;
    left: 140px;
    top: 15px;
    font-size: 15px;
    font-weight: 500;
}
.wrapper ul li .say{
    position: absolute;
    bottom: 10px;
    left: 45px;
    font-size: 14px;
    color: rgb(97, 86, 86);
}

注意不要让Female的字体露出盒子。

JS代码

// 从后端请求来的数据
var personArr = [
    {name: '李白', age: 21, sex: 'male', email: '111@163.com'},
    {name: '韩信', age: 23, sex: 'male',email: '222@163.com'}, 
    {name: '嬴政', age: 25, sex: 'male', email: '777@163.com'}, 
    {name: '元歌', age: 27, sex: 'male',email: '333@163.com'}, 
    {name: '王朝君', age: 20, sex: 'female', email: '222@163.com'}, 
    {name: '露娜', age: 22, sex: 'female', email: '666@163.com'},
    {name: '李元芳', age: 23, sex: 'male',email: '333@163.com'}, 
    {name: '伽罗', age: 21, sex: 'female', email: '222@163.com'}, 
    {name: '花木兰', age: 25, sex: 'female', email: '666@163.com'}
];





// initial variable
var oUl = document.getElementsByTagName("ul")[0];
var oInput = document.getElementsByTagName("input")[0];


// 数据渲染到页面
function randerPage (data) {
    // 遍历数据,并把数据填入页面之中
    var htmlStr = "";

    // 防止请求数据不成功导致出BUG
    oUl.innerHTML = "";
    data.forEach(function (ele, index, self) {

        // 字符串拼接方法
        htmlStr += "<li><img src='./1.png'><p class='name'>" + ele.name + "</p><p class='age'>" + ele.age + "</p><p class='say'>" + ele.email + "</p>";
    });

    // 将拼接好的字符串插入到页面中
    oUl.innerHTML = htmlStr;
}


// 首次渲染得到初始页面
randerPage(personArr);





// 添加行为

// 输入框行为
oInput.oninput = function () {

    // 把根据文本筛选出的数据传入渲染函数中进行渲染
    randerPage(filterArrByText(personArr, this.value));

}

// 根据文本来进行筛选函数(纯函数)
function filterArrByText (data, text) {
    if (!text) {
        return data;
    }else{

        // 返回筛选出的数据
        return data.filter(function (ele, index) {

            // 返回符合文本条件的数据
            return ele.name.indexOf(text) != -1; 
        });
    }
}





// btn varible
// 原生方法获取到一堆的DOM元素时,得到的是个类数组
var oBtnArr  = [].slice.call(document.getElementsByTagName("button"), 0);

 //获取上一次具有被点击样式的元素
var lastActiveBtn = document.getElementsByClassName("active")[0];        


// btn 点击样式行为

// 注册事件
oBtnArr.forEach(function(ele, index, self) {
    ele.onclick = function () {

        // 当一点击性别,css样式就发生改变
        changeStyle(this);
        
        if (ele.innerText != "age") {

            // 按点击到的性别重新渲染一遍页面
            randerPage(filterArrBySex(personArr, ele.innerText));
        }else{

            // 按点击到的年龄重新渲染一遍页面,因为数组方法sort会改变原数组,所以用克隆的数据进行sort操作
            var arr = [];
            randerPage(sortByAge(clone(arr, personArr)));
        }
    }
})





// 点击按钮时css样式改变函数
function changeStyle (currActiveBtn) {

    // 当前被点击的元素具有active样式
    currActiveBtn.className = "active";

    // 把上次被点击的元素的样式清除
    lastActiveBtn.className = "";

    // 更新上次被点击的元素,以便后续点击操作
    lastActiveBtn = currActiveBtn;
}





// 根据性别来筛选数据函数
function filterArrBySex (data, sex) {

    // 默认和用户点击All按钮
    if (sex == "All") {

        // 不进行操作,返回原数组
        return data;
    }else {

        // 返回根据性别筛选出来的数据
        return data.filter(function (ele, index) {

            // 因为请求来的数据的性别首字母是小写,而行间里的是大写,所以用正则将点击到的行间里的性别替换成小写
            var reg = /^\w/g;

            // 返回数据中具有相同的性别的一些数据,因为别正则不改变原字符串,所以不需要克隆点击到的字符,
            return ele.sex == sex.replace(reg, function ($) {
                return $.toLowerCase(); 
            });
        });
    }
}





// 根据年龄对数据进行排序
function sortByAge (data) {
    data.sort(function (a, b) {

        // 从小到大排
        return a.age - b.age
    });

    // 排序结果为一个类数组,所以调用数组方法空截,得到数组,(否则后续将排序的数据渲染到页面时调用不了forEach方法)
    return [].slice.call(data, 0)
}  



// 深度克隆
function clone (target, orange) {

	// 兼容用户不传接收克隆好的数据的数组或对象
	var target = target || {};

	// 判断要克隆的是数组还是对象的方法
	var toStr = Object.prototype.toString;

	// 将判断要克隆的是数组的条件存一下
	var str = "[object Array]"

	// 遍历要克隆的数据
	for (var prop in orange) {

		// 剔除原型上的属性
		if (orange.hasOwnProperty(prop)) {

			// 剔除除null外的原始值
			if (orange !== null && typeof(orange[prop]) == "object") {

				// 用储存的方法和条件值判断要克隆的是数组还是对象
				target[prop] = toStr.call(orange[prop]) == str ? [] : {};

				// 递归克隆对象里还有对象的情况
				clone(target[prop], orange[prop])
			}else {

				// 原始值直接克隆
				target[prop] = orange[prop];
			}
		}
	}

	// 最后返回克隆好的数据
	return target;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值