数组方法小demo
这次主要是利用数组的一些方法来进行一些小应用,如forEach方法和filter方法
html由两部分组成,分别为顶部搜索框部分和下面的好友列表部分
代码(静态THML页面):
<div class="wrapper">
<div class="filterFunc">
<input type="text" class="search"></input>
<span class="btn">Java</span>
<span class="btn">Web</span>
<span class="btn active">All</span>
</div>
<div class="friendList">
<ul>
<!--
<li>
<img src="./arr-img/1.png" alt="">
<p class="name">111</p>
<p class="des">111</p>
</li>
<li>
<img src="./arr-img/2.png" alt="">
<p class="name">222</p>
<p class="des">222</p>
</li>
<li>
<img src="./arr-img/3.png" alt="">
<p class="name">333</p>
<p class="des">333</p>
</li>
<li>
<img src="./arr-img/4.png" alt="">
<p class="name">444</p>
<p class="des">444</p>
</li>
<li>
<img src="./arr-img/5.png" alt="">
<p class="name">555</p>
<p class="des">555</p>
</li>
-->
</ul>
</div>
</div>
css部分,在好友列表样式部分,布局可通过以下方式实现,img标签以absolute方式进行定位,文字标签则利用li的padding属性进行位置控制,通过padding-top和padding-bottom使文字部分在垂直方向上居中,通过padding-left属性将文字部分挤到右边,使其不被图片覆盖
/* css reset */
*{
padding: 0;
margin: 0;
list-style: none;
}
.wrapper{
padding: 10px 15px;
width: 400px;
margin: 100px auto 0;
border: 1px solid #ccc;
border-radius: 5px;
}
/* filterFunc section style */
.wrapper .filterFunc{
margin-bottom: 20px;
}
.wrapper .filterFunc .search{
width: 250px;
height: 20px;
border: 1px solid #999;
padding-left: 10px;
outline: none;
border-radius: 4px;
}
.wrapper .filterFunc .btn{
color: #3c8dff;
cursor: pointer;
padding: 0 5px;
border-radius: 4px;
}
.wrapper .filterFunc .active{
color: #fff;
background-color: #3c8dff;
}
/* friendList section style */
.wrapper .friendList ul li{
position: relative;
padding-top: 10px;
padding-bottom: 10px;
padding-left: 50px;
border-bottom: 1px solid #999;
}
.wrapper .friendList ul li img{
position: absolute;
left: 0;
top: 10px;
width: 40px;
height: 40px;
}
.wrapper .friendList ul li .name{
margin-bottom: 10px;
}
.wrapper .friendList ul li .des{
color: #666;
font-size: 12px;
}
同时也可以利用JS来动态地为页面ul加载li标签及内部标签,这里主要通过forEach方法实现,代码如下:
//原始数据
var personArr = [
{name: '坤子锅', src:'./arr-img/1.png', des: '坤坤爱学习', job: 'Java'},
{name: '凯子锅', src:'./arr-img/2.png', des: '篮球爱学习', job: 'Java'},
{name: '东子锅', src:'./arr-img/3.png', des: '唱', job: 'Web'},
{name: '晓子锅', src:'./arr-img/4.png', des: '跳', job: 'Web'},
{name: '楠子锅', src:'./arr-img/5.png', des: 'rap爱学习', job: 'Web'},
];
//获取ul标签
var oUl = document.getElementsByClassName('friendList')[0].getElementsByTagName('ul')[0];
renderPage(personArr);
//通过遍历数组来为ul部分添加内容
function renderPage(data){
var htmlStr = '';
data.forEach(function (ele, index, self) {
//ele.name => p.name
//ele.src => img src
//ele.des => p.des
htmlStr += '<li><img src="' + ele.src + '"><p class="name">' + ele.name + '</p><p class="des">' + ele.des + '</p></li>';
});
oUl.innerHTML = htmlStr;
}
这里的效果如下:
然后为input和span标签添加事件来实现关键字查询功能,其中查询筛选功能主要通过filter方法来进行实现,在筛选操作结束后,再利用前面的renderPage来对页面进行渲染即可实现关键字或属性的查询功能,在上述操作中,按钮事件的绑定通过forEach函数实现,dom获取节点返回的结果为类数组(实质上即为对象),为使类数组可以使用forEach方法,这里可通过slice方法来将类数组转为数组,代码如下:
var state = {
text : '',
job : 'All'
};
//获取输入框标签
var oInput = document.getElementsByClassName('search')[0];
//合并筛选函数
var lastFilterFunc = combineFilterFunc({text: filterArrayByText, job: filterArrayByJob})
//为输入框绑定oninput事件,当input框内的内容发生变化时,检测并执行事件内容
oInput.oninput = function () {
state.text = this.value;
renderPage(lastFilterFunc(personArr));
}
// 为所有按钮绑定事件
var oButtonArr = document.getElementsByClassName('btn');
//通过slice方法来将类数组转换为数组
oButtonArr = Array.prototype.slice.call(oButtonArr);
var lastActiveBtn = oButtonArr[oButtonArr.length - 1];
oButtonArr.forEach(function (ele, index, self){
ele.onclick = function(){
//在点击事件执行后,执行更换类名函数
changeActive(this);
state.job = this.innerText;
//通过两次过滤来完成两种属性筛选
renderPage(lastFilterFunc(personArr));
}
});
//替换标签类名
function changeActive(ele){
// 初始的active按钮为all,其位置为oButtonArr.length-1,将当前点击标签的className变为active,并将上一个active标签类名中的active清掉,最后将lastActiveBtn变为当前点击的标签,以供下次点击使用
ele.className = 'btn active';
lastActiveBtn.className = 'btn';
lastActiveBtn = ele;
}
为优化代码,这里将通过输入框筛选的函数filterArrayByText和通过按钮筛选的函数filterArrayByJob进行封装,最后采用一个lastFilterFunc来完成筛选,筛选函数的代码如下:
//根据输入框内容筛选
function filterArrayByText(data, text){
// 若input中的内容为空,则不进行过滤
if (!text){
return data;
}
return data.filter(function (ele, index, self) {
return ele.name.indexOf(text) !== -1;
});
}
//根据工作筛选
function filterArrayByJob(data, job){
// 若input中的内容为空,则不进行过滤
if (job === 'All'){
return data;
}
return data.filter(function (ele, index, self) {
return ele.job.indexOf(job) !== -1;
});
}
//conbineFilterFunc
//合并filterArrayByText filterArrayByJob ......
function combineFilterFunc(config){
return function (data){
var lastArr = data;
for (var prop in config){
//prop = 'text' 'job'
//config[prop] = filterArrayByText
//config[prop] = filterArrayByJob
lastArr = config[prop](lastArr, state[prop])
}
return lastArr;
}
}
最终效果展示,可通过按钮和输入框进行混合查询
1、按钮查询
2、输入框查询
3、混合查询