算是一个dome功能,实现之后的样式是这样的
类似于选项卡,当点击all展示所有的卡片
当点击Female的时候会展示所有男性的卡片
反之点击女性也是一样的
并且还有条件筛选,当点击输入九的时候会展示所有字符当中含有九的男性
该dome运动的一些方法有:
forEach,数组遍历方法
Filter,数组筛选方法
for in 循环,遍历对象方法
indexOf,判断当前值是包含有里面的值
getAttribute 读取元素属性的值
JS设计模式思想(人懵的)
以下是初级代码实现该功能
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
*{
padding: 0;
margin: 0;
list-style: none;
}
.wrapper{
width: 400px;
padding: 10px 15px;
border: 1px solid #ccc;
margin: 100px auto 0px;
border-radius: 6px;
}
.wrapper .sWrapper{
margin-bottom: 20px;
}
.wrapper .sWrapper .sText{
width: 220px;
height: 25px;
padding-left: 10px;
outline: none;
border-radius: 4px;
border: 1px solid #777;
}
.wrapper .sWrapper .btn{
cursor: pointer;
color: #3c8dff;
padding: 0px 5px;
}
.wrapper .sWrapper .btn.active{
color: #fff;
background-color: #3c8dff;
border-radius:5px;
}
.wrapper .flWrapper ul li{
border-bottom: 1px solid #999;
position: relative;
padding-left: 45px;
padding-top: 10px;
padding-bottom: 5px;
}
.wrapper .flWrapper ul li img{
position: absolute;
width:36px;
height:36px;
left: 0;
top: 14px;
}
.wrapper .flWrapper ul li .des{
font-size: 12px;
color: #666;
margin-top: 5px;
}
</style>
</head>
<body>
<div class="wrapper">
<div class="sWrapper">
<input type="text" class="sText">
<span sex='m' class="btn">Male</span>
<span sex='f' class="btn">Female</span>
<span sex='a' class="btn active">All</span>
</div>
<div class="flWrapper">
<ul></ul>
</div>
</div>
var personArr = [
{'name' : "九依", 'src' : "./img/1.jpg", 'sex' : 'f', 'age' : '19', 'des' : "太高了"},
{'name' : "夕灿", 'src' : "./img/2.jpg", 'sex' : 'm', 'age' : '19', 'des' : "啊哈哈哈"},
{'name' : "夕阳灿", 'src' : "./img/3.jpg", 'sex' : 'm', 'age' : '19', 'des' : "今天还没吃饭"},
{'name' : "小宁", 'src' : "./img/4.jpg", 'sex' : 'f', 'age' : '19', 'des' : "我叫什么"},
{'name' : "九测", 'src' : "./img/5.jpg", 'sex' : 'f', 'age' : '19', 'des' : "办法没办法"},
];
//
var oUl = document.getElementsByTagName('ul')[0];
var oInput = document.getElementsByTagName('input')[0];
//记录当前输入的文本
var filterText = '';
//记录性别
var filterSex = 'a';
function RenderPage (data){
// 遍历
var htmlStr = ' ';
oUl.innerHTML = ' ';
data.forEach(function (ele ,index ,self) {
//字符串拼接代码
htmlStr = htmlStr + '<li><img src = "' + ele.src + '"></img><p class = "name">' + ele.name+ '</p><p class = "des">' + ele.des + '</p></li>'
})
oUl.innerHTML = htmlStr;
}
RenderPage(personArr)
//添加行为
oInput.oninput = function(data) {
//当输入框输入的时候不断触发
//不断去记录当前输入的值
filterText = this.value;
//执行渲染 文本过滤方法 //数组 输入的值进行渲染
//1. RenderPage(filterArrByText(personArr,this.value))
//将符合条件的数组存入 过滤文本方法 原始数组 输入的值
var newArr = filterArrByText( personArr, filterText)
//将符合条件的数组存入 过滤性别的方法 之后的数组 输入的值
var newArr2 = filterArrBySex( newArr, filterSex);
//执行符合之后的数组
RenderPage(newArr2)
}
//根据文本进行过滤的函数 纯函数
// 传入的数组 输入的值
function filterArrByText (data, text){
if (!text){
//如果没有值或者是空直接返回数组
return data;
}else{
// 返回一个过滤后的数组 //数组 //位置
return data.filter(function (ele, index){
// 判断数组的Name是否符合条件判断
return ele.name.indexOf(text) != -1;
})
}
}
//按钮切换的颜色
//获取当前按钮的所有数组
//获取的是一个类数组,需要用数组的slice方法来让他变为数组
var oBtnArr = [].slice.call(document.getElementsByClassName('btn'), 0);
//记忆初始按钮的位置
var lastActiveBtn = oBtnArr[2];
//遍历数组按钮 数组 位置 数组列
oBtnArr.forEach(function(ele, index, self){
//当点击的时候触发事件
ele.onclick = function(){
//用更改样式的函数 传入当前点击的按钮
changeActive(this);
filterSex = this.getAttribute('sex')
// getAttribute读出当前按钮属性的值
//1. RenderPage(filterArrBySex(personArr, this.getAttribute('sex')));
//将符合条件的数组存入 性别过滤方法 原始数组 输入的值
var newArr = filterArrBySex(personArr, filterSex)
//将符合条件的数组存入 过滤文本方法 之后数组 输入的值
var newArr2 = filterArrByText(newArr, filterText);
//执行符合之后的数组
RenderPage(newArr2);
}
})
//更改样式的函数方法 //点击的按钮
function changeActive (curActiveBtn){
//如果当前点击的按钮是重复样式值就空执行
if(curActiveBtn.className == 'btn active'){
}else{
//否则就执行
curActiveBtn.className = 'btn active';
//让初始的样式变为无样式
lastActiveBtn.className = 'btn';
//记忆上一个点击的按钮位置
lastActiveBtn = curActiveBtn;
}
}
//根据性别过滤的函数方法 //数组 点击的性别
function filterArrBySex(data, sex){
//如果性别等于all
if ( sex == 'a'){
//直接返回当前的数组
return data;
}else{
//过滤 数组的筛选方法 数组索引每一列 数组索引 数组
return data.filter(function (ele, index, self){
//返回当前点击的性别
return ele.sex == sex;
})
}
}
迭代优化,高级模式
优点化
条件增加导致行为增加该如何统一处理
诸多状态如何管理
行为频繁触发操作dom如何提高性能
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
*{
padding: 0;
margin: 0;
list-style: none;
}
.wrapper{
width: 400px;
padding: 10px 15px;
border: 1px solid #ccc;
margin: 100px auto 0px;
border-radius: 6px;
}
.wrapper .sWrapper{
margin-bottom: 20px;
}
.wrapper .sWrapper .sText{
width: 220px;
height: 25px;
padding-left: 10px;
outline: none;
border-radius: 4px;
border: 1px solid #777;
}
.wrapper .sWrapper .btn{
cursor: pointer;
color: #3c8dff;
padding: 0px 5px;
}
.wrapper .sWrapper .btn.active{
color: #fff;
background-color: #3c8dff;
border-radius:5px;
}
.wrapper .flWrapper ul li{
border-bottom: 1px solid #999;
position: relative;
padding-left: 45px;
padding-top: 10px;
padding-bottom: 5px;
}
.wrapper .flWrapper ul li img{
position: absolute;
width:36px;
height:36px;
left: 0;
top: 14px;
}
.wrapper .flWrapper ul li .des{
font-size: 12px;
color: #666;
margin-top: 5px;
}
</style>
</head>
<body>
<div class="wrapper">
<div class="sWrapper">
<input type="text" class="sText">
<span sex='m' class="btn">Male</span>
<span sex='f' class="btn">Female</span>
<span sex='a' class="btn active">All</span>
</div>
<div class="flWrapper">
<ul></ul>
</div>
</div>
<script src="./js/tool.js"></script>
<script src="./js/filter/filterArrBySex.js"></script>
<script src="./js/filter/filterArrByText.js"></script>
<script src="./js/combineFilter.js"></script>
<script src="./js/createStore.js"></script>
<script src="./js/index.js"></script>
</body>
</html>
var personArr = [
{'name' : "九依", 'src' : "./img/1.jpg", 'sex' : 'f', 'age' : '19', 'des' : "太高了"},
{'name' : "夕灿", 'src' : "./img/2.jpg", 'sex' : 'm', 'age' : '19', 'des' : "啊哈哈哈"},
{'name' : "夕阳灿", 'src' : "./img/3.jpg", 'sex' : 'm', 'age' : '19', 'des' : "今天还没吃饭"},
{'name' : "小宁", 'src' : "./img/4.jpg", 'sex' : 'f', 'age' : '19', 'des' : "我叫什么"},
{'name' : "九测", 'src' : "./img/5.jpg", 'sex' : 'f', 'age' : '19', 'des' : "办法没办法"},
];
var oUl = document.getElementsByTagName('ul')[0];
var oInput = document.getElementsByTagName('input')[0];
store.subscribe(function (){
//更新页面和视图的作用
//调用整合方法工具
RenderPage(lsatFilterArr(personArr));
})
function RenderPage (data){
var htmlStr = ' ';
oUl.innerHTML = ' ';
data.forEach(function (ele ,index ,self) {
htmlStr = htmlStr + '<li><img src = "' + ele.src + '"></img><p class = "name">' + ele.name+ '</p><p class = "des">' + ele.des + '</p></li>'
})
oUl.innerHTML = htmlStr;
}
RenderPage(personArr)
//防抖
oInput.oninput = debounce(function(data) {
//调用store的订阅方法 文本 当前文本框的值
store.dispatch({type : 'text', value : this.value },50)
})
var oBtnArr = [].slice.call(document.getElementsByClassName('btn'), 0);
var lastActiveBtn = oBtnArr[2];
oBtnArr.forEach(function(ele, index, self){
ele.onclick = function(){
changeActive(this);
//调用store的订阅方法 性别筛选 读按钮属性的值
store.dispatch({type : 'sex', value : this.getAttribute('sex') })
}
})
function changeActive (curActiveBtn){
if(curActiveBtn.className == 'btn active'){
}else{
curActiveBtn.className = 'btn active';
lastActiveBtn.className = 'btn';
lastActiveBtn = curActiveBtn;
}
}
在此基础上引入了一个工具集合包
//封装一个工具库 传入的两个方法
function combineFilter(config){
//返回一个函数 数组
return function (data){
//遍历对象 遍历每个方法
for (var prop in config){
// console.log(prop, config[prop], state[prop])
//data等于筛选完之后的数组 第一个方法 数组 筛选条件
data = config[prop](data,store.getState(prop))
}
//返回数组
return data;
}
}
//lastFilterArr相当于对象合集,他等于执行一个对象之后的结果
var lsatFilterArr = combineFilter({
text : filterArrByText,
sex : filterArrBySex
})
引入方法功能 filterArrByText
function filterArrByText (data, text){
if (!text){
return data;
}else{
return data.filter(function (ele, index){
return ele.name.indexOf(text) != -1;
})
}
}
引入方法功能 filterArrBySex
function filterArrBySex(data, sex){
if ( sex == 'a'){
return data;
}else{
return data.filter(function (ele, index, self){
return ele.sex == sex;
})
}
}
封装接口 combineFilter
//封装一个工具库 传入的两个方法
function combineFilter(config){
//返回一个函数 数组
return function (data){
//遍历对象 遍历每个方法
for (var prop in config){
// console.log(prop, config[prop], state[prop])
//data等于筛选完之后的数组 第一个方法 数组 筛选条件
data = config[prop](data,store.getState(prop))
}
//返回数组
return data;
}
}
//lastFilterArr相当于对象合集,他等于执行一个对象之后的结果
var lsatFilterArr = combineFilter({
text : filterArrByText,
sex : filterArrBySex
})
笔记自渡一教育,哎人给我看傻了。