改造jQuery.chosen.js,可进行远程搜索

由于项目需求,需要通过下拉框选择用户,而系统中的用户有1w多人,通过chosen插件生成下拉框的话,会造成页面卡顿。

解决方案

  • 将用户数据存入localStorage
  • 改造chosen插件,当用户搜索时,去localStorage获取匹配数据

具体思路

  • 从localStorage获取用户数据,保存到全局变量chosenUserList
  • 如何没有数据,则通过ajax从数据库获取数据,并保存到localStorage和赋值给chosenUserList
  • 生成chosen控件
  • 监听chosen搜索框的input事件
  • 当input事件触发时,设置定时器执行数据查询操作并更新chosen控件

select标签如下:

chosen-user用于初始化时识别,select-item用于保存选中项的值

<select name='' chosen-user select-item=''><option value=''></option></select>

具体代码如下:

<?php
// 引入jquery.chosen.js
css::import($zuiRoot . 'lib/chosen/chosen.min.css');
js::import($zuiRoot . 'lib/chosen/chosen.min.js');
?>
<script>
// 配置项
var ChosenUserOptions = {
    no_results_text: '没有找到结果', 
    no_query_text: '请输入',
    width:'100%', 
    allow_single_deselect: true, 
    placeholder_text_single: ' ', 
    placeholder_text_multiple: ' ', 
    search_contains: true
};
var chosenUserList = null;//用户列表
var chosenUserSearchKey = '';//用户搜索值
var chosenUserSearchTimer = '';//执行用户模糊搜索定时器

$(function(){
    // 从localStorage获取用户列表
    chosenUserList = JSON.parse(localStorage.getItem("chosenUserList"));

    // 当数据不存在时,通过ajax去数据库获取,并存入localStorage
    if (!chosenUserList) {
        $.ajax({
            url: "index.php?m=user&f=ajaxGetAllUser",
            type: 'POST',
            data: {},
            async: false,
            dataType: 'json',
            success: function(data){
                chosenUserList = data;

                // 将json对象转换为字符串,再存入localStorage
                localStorage.setItem("chosenUserList", JSON.stringify(data));
            }
        })
    }
    initChosenUser();
})
function initChosenUser(){
    // 遍历所有需要生成chosen的select元素,这里我的标记是有属性chosen-user的select标签
    $('[chosen-user]').each(function(){
        // 获取已选选项的数组和option字符串
        let selectObj = genChosenUserSelected($(this));

        //添加选中项
        $(this).html(selectObj.option);

        //初始化控件
        var chosen = $(this).chosen(ChosenUserOptions).on('change', function(){
            changeChosenUser($(this));// 当值改变时,更新属性select-item
        })

// console.dir(chosen.data('chosen'));

        //监听搜索事件,当用户停止输入500毫秒后,执行操作
        chosen.data('chosen').search_field.on('input', function(){
            $this = $(this);
            if (chosenUserSearchTimer) {
                clearTimeout(chosenUserSearchTimer);
            }
            chosenUserSearchTimer = setTimeout(function() {
                let selectObj = genChosenUserSelected($this.parents('.chosen-container').prev('select'));
                let tmpOption = '';
                let searchKey = $this.val(); // 搜索值
                if ($.trim(searchKey) != '') {
                    for (let i in chosenUserList) {
                        if (chosenUserList[i].indexOf(searchKey) !== -1 && selectObj.array.indexOf(i) === -1) {
                            // 选项匹配搜索值 && 选项在在选中选项中不存在
                            tmpOption += `<option value="${i}">${chosenUserList[i]}</option>`;
                        }
                    }
                }
                chosenUserSearchKey = searchKey;// 保存用户输入
                chosen.html(selectObj.option + tmpOption).trigger("chosen:updated");//更新chosen选项、会清空搜索框
                chosen.data('chosen').search_field.val(chosenUserSearchKey).keydown();//将用户输入值放回搜索框,这里触发keydown可以设置搜索框宽度
            }, 500);
        })
    })
}

/**
 * 获取已选选项的数组和option字符串
 * @param {Object} $select select Dom
 */
function genChosenUserSelected($select){
    let selectOption = '<option value=""></option>';
    let selectItemArr = $select.attr('select-item').split(',');
    if (selectItemArr.length > 0) {
        for (let i in selectItemArr) {
            for (let account in chosenUserList) {
                if (account == selectItemArr[i]) {
                    selectOption += `<option value="${account}" selected>${chosenUserList[account]}</option>`;
                    break;
                }
            }
        }
    }
    return {
        array: selectItemArr,
        option: selectOption
    }
}

/**
 * 修改Select标签的属性
 * @param {Object} $select select Dom
 */
function changeChosenUser($select){
    if (Array.isArray($select.val())) {
        $select.attr('select-item', $select.val().join(','));
    } else {
        $select.attr('select-item', $select.val());
    }
    
}
</script>

$(select).chosen(option),将返回的内容保存到select元素的data('chosen')中

var obj = $(select).chosen(option);
console.dir(obj.data('chosen'));

search_field 为搜索框的input元素,其他属性不一一介绍,大家可以把它打到控制台自行查看

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值