input动态搜索下拉框组件input-dynamic-select使用(二)

上一篇 input动态搜索下拉框组件input-dynamic-select使用(一) 大致介绍了input-dynamic-select组件的使用方法,现在通过一个demo具体介绍这个组件的使用方法。我使用node的express的框架简单搭建了一个后台服务接口,前端通过调用这个接口获取数据。

demo代码见:https://github.com/yog-zhang/input-dynamic-select.git

1.整体结构

首先,这个demo的整体结构如下:

构建打包工具使用的是webpack,打包入口文件是index.js,服务接口api写在server.js文件中

最后呈现的效果如下:

2.搭建后台服务

在终端输入 node server.js命令启动后台服务,后台服务接口地址为:http://localhost:8088/mock,这个接口接受一个参数keywords,这个参数就是在input输入框输入的查询关键字,接口根据查询关键字返回数据。这里为了简单清晰说明问题,用一个数组模拟从数据库查询数据,不是真从数据库查询数据,代码如下:

app.get('/mock', function(req, res){
    let keywords = req.query['keywords']
    console.log('keywords:',keywords)
    let result = []
    let dataList = Array.of(
        "男子单打羽毛球",
        "女子单打羽毛球",
        "男子双打羽毛球",
        "女子双打羽毛球",
        "男女混双羽毛球",
        "男子单打乒乓球",
        "女子单打乒乓球",
        "男子双打乒乓球",
        "女子双打乒乓球",
        "男女混双乒乓球",
        "男子单打网球",
        "女子单打网球",
        "男子双打网球",
        "女子双打网球",
        "男女混双网球"
        )
    if(keywords && keywords.trim()){
        result = dataList.filter((val) => {
            return val.indexOf(keywords) > -1
        })
    }
    res.append('content-type','application/json;charset=utf-8')
    res.end(JSON.stringify(result))
})

3.前端调用

input.html 代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>input-dynamic-select</title>
</head>
<body>
    <div class='inputPanel' style="width: 200px;">
        <span>比赛项目:</span>
        <input type="text" id="inputId"/>
    </div>
</body>
</html>

在HTML中要写一个input元素,赋给它一个id选择器,这个id会和后面的动态下拉框进行绑定。

import $ from 'jquery'
import DSelect from 'input-dynamic-select' 

//新建DSelect实例,通过'inputId'绑定input输入框
let dSelect = new DSelect('inputId',
    [
        // ul元素上的类iuds-selectPanel-n的样式(n是当时创建的DSelect实例序列)
        {
            'display': 'none',
            'list-style-type': 'none',
            'margin': '0',
            'padding': '0',
            'border': '1px solid #d9d9d9',
            'background-color': '#ceffff',
            'width': '160px',
            'height': '200px',
            'overflow-y': 'auto'
        },
        // li元素上的样式
        {
            'padding-left': '5px',
            'line-height': '30px'
        },
        // 悬浮在li元素上的样式
        {
            'background-color': '#d9d9d9',
            'cursor': 'pointer'
        },
        // li元素下面span元素上的样式
        {
            'color': 'red',
            'font-weight': 'bolder'
        }
    ]
)
// ajax请求方法
function ajaxFn(keywords){
    $.ajax({
        type: 'GET',
        url: `/mock?keywords=${keywords}`,
        async: true,
        contentType: 'application/json;charset=utf-8',
        success: function(data){
            if(data && data.length > 0){
                dSelect.setDataList(data)
            }
        },
        error:function(e){
            console.log(e)
        }
    })
}

let inputNode = document.querySelector('#inputId')

// 监听input输入框的input事件,动态从后台获取数据
inputNode.addEventListener('input', (e) => {
    let keywords = e.currentTarget.value
    ajaxFn(keywords)
})

显示效果:

根据输入的关键字进行实时从后台取数据,然后渲染下拉列表。

当然想要它渲染中什么样式,比如字体颜色、背景色、行高等等都可以自己去设置,自由权完全在你。

new DSelect(id, styleArray),第二个数组参数一个可以设置四个子元素,每个元素都可以为null,为null则会展示默认样式,但是如果里面如果有一个子元素不为空,那其他为null的子元素不能省略不写,要写上null,像这样:

let dSelect = new DSelect('inputId',
    [
        // ul元素上的类iuds-selectPanel-n的样式(n是当时创建的DSelect实例序列)
        {
            'display': 'none',
            'list-style-type': 'none',
            'margin': '0',
            'padding': '0',
            'border': '1px solid #d9d9d9',
            'background-color': '#ceffff',
            'width': '160px',
            'height': '200px',
            'overflow-y': 'auto'
        },

        // li元素上的样式
        // 不能省略不写
        null,

        // 悬浮在li元素上的样式
        // 不能省略不写
        null,

        // li元素下面span元素上的样式
        {
            'color': 'red',
            'font-weight': 'bolder'
        }
    ]
)

但是如果数组子元素全为空,则可以直接这样写:

let dSelect = new DSelect('inputId',null)

或者直接不写第二个参数:

let dSelect = new DSelect('inputId')

4.敲击下拉框元素外部,将下拉框隐藏

你可能发现,当下拉框渲染出来的时候,还没有进行选择,你点击下拉框的外部区域,下拉框一直在,没有消失,这可能不太符合需求。当然这个功能我本来打算包含在组件中,但发现由于每个人的页面结构以及个人的需求不一样,不好写成统一的格式,所以还是交给自己去实现这个功能,当然也挺简单的,直接写一个click监听事件,当监测到不是下拉框元素时(一般是input元素和下拉框元素的父元素),就将下拉框元素隐藏掉:

import $ from 'jquery'
import DSelect from 'input-dynamic-select' 

//新建DSelect实例,通过'inputId'绑定input输入框
let dSelect = new DSelect('inputId',
    [
        // ul元素上的类iuds-selectPanel-n的样式(n是当时创建的DSelect实例序列)
        {
            'display': 'none',
            'list-style-type': 'none',
            'margin': '0',
            'padding': '0',
            'border': '1px solid #d9d9d9',
            'background-color': '#ceffff',
            'width': '160px',
            'height': '200px',
            'overflow-y': 'auto'
        },
        // li元素上的样式
        {
            'padding-left': '5px',
            'line-height': '30px'
        },
        // 悬浮在li元素上的样式
        {
            'background-color': '#d9d9d9',
            'cursor': 'pointer'
        },
        // li元素下面span元素上的样式
        {
            'color': 'red',
            'font-weight': 'bolder'
        }
    ]
)
// ajax请求方法
function ajaxFn(keywords){
    $.ajax({
        type: 'GET',
        url: `/mock?keywords=${keywords}`,
        async: true,
        contentType: 'application/json;charset=utf-8',
        success: function(data){
            if(data && data.length > 0){
                dSelect.setDataList(data)
            }
        },
        error:function(e){
            console.log(e)
        }
    })
}

let inputNode = document.querySelector('#inputId')

// 监听input输入框的input事件,动态从后台获取数据
inputNode.addEventListener('input', (e) => {
    let keywords = e.currentTarget.value
    ajaxFn(keywords)
})

//当敲击动态下拉框元素之外的元素时,隐藏下拉框
document.body.addEventListener('click',function(e){
    let inputPanel = document.querySelector('.inputPanel')
    if(!inputPanel.contains(e.target)){
        dSelect.getOptions().selectNode.style.display = 'none'
    }
})

input-dynamic-select插件的使用方法大致就介绍完了。

水平有限,欢迎批评指正!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章