原生JS实现好友列表查询demo

数组方法小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、混合查询
混合查询

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值