JavaScript根据Json数据来做的模糊查询功能

Posted rookieM的小黑屋

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaScript根据Json数据来做的模糊查询功能相关的知识,希望对你有一定的参考价值。

类似于百度搜索框的模糊查找功能

需要有有已知数据,实现搜索框输入字符,然后Js进行匹配,然后可以通过鼠标点击显示的内容,把内容显示在搜索框中

当然了,正则只是很简单的字符匹配,不具备多么复杂的判断

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>模糊查询</title>
    <style>
        *{
            list-style: none;
            padding:0;
            margin:0;
        }
        div{
            text-align: center;
            padding-top:20px;
        }
        ul{
            padding-top:20px;
            width:30%;
            margin:0 50% 0 35%;
        }
        li{
            padding:3px;
            border:1px solid silver;
            box-shadow: 1px 1px;
        }
    </style>
</head>
<body>
    <div>
        <input type="text" id="txt">
        <button type="button" id="btn">search</button>
        <ul id="list">

        </ul>
    </div>
    <script>
                
var oTxt = document.getElementById(txt);
var oBtn = document.getElementById(btn);
var oList = document.getElementById(list);

// var newJson = ["桃子", "苹果", "梨子", "香蕉", "香瓜", "葡萄", "柠檬", "橘子", "草莓"];


var newJson= ["桃子", "苹果", "梨子", "香蕉", "香瓜", "葡萄", "柠檬", "橘子", "草莓"];
//点击事件
oTxt.addEventListener(keyup, function () {
    checkCharacter();
    var keyWord = oTxt.value;
    // var fruitList = searchByIndexOf(keyWord,newJson);
    // console.log(fruitList);
    var fruitList = searchByRegExp(keyWord, newJson);
    renderFruits(fruitList);
    showClickDiv();
}, false);
//回车查询
oTxt.addEventListener(keydown, function (e) {
    if (e.keyCode == 13) {
        var keyWord = oTxt.value;
        // var fruitList = searchByIndexOf(keyWord,newJson);
        var fruitList = searchByRegExp(keyWord, newJson);
        renderFruits(fruitList);
    }
}, false);


function showClickDiv() {
    var liList = oList.getElementsByTagName("li");
    console.log(liList);
    for (var i = 0; i < liList.length; i++) {
        liList[i].onclick = function () {
            console.log(this.innerHTML);
            showClickTextFunction(this.innerHTML);
        }
    }
}

function checkCharacter() {
    var etest = oTxt.value;
    if (etest == ‘‘ || etest == null || etest == undefined) {
        oList.style.display = "none";
        return false;
    } else {
        oList.style.display = "block";
    }
}

function renderFruits(list) {
    if (!(list instanceof Array)) {
        return;
    }
    oList.innerHTML = ‘‘;
    var len = list.length;
    var item = null;
    for (var i = 0; i < len; i++) {
        item = document.createElement(li);
        item.innerHTML = list[i];
        oList.appendChild(item);
    }
}

//模糊查询1:利用字符串的indexOf方法
function searchByIndexOf(keyWord, list) {
    if (!(list instanceof Array)) {
        return;
    }
    var len = list.length;
    var arr = [];
    for (var i = 0; i < len; i++) {
        //如果字符串中不包含目标字符会返回-1
        if (list[i].indexOf(keyWord) >= 0) {
            arr.push(list[i]);
        }
    }
    return arr;
}
//正则匹配
//keyword是输入的值,list是存储数据的数组
function searchByRegExp(keyWord, list) {
    if (!(list instanceof Array)) {
        return;
    }
    var len = list.length;
    var arr = [];
    var reg = new RegExp(keyWord);
    for (var i = 0; i < len; i++) {
        //如果字符串中不包含目标字符会返回-1
        if (list[i].match(reg)) {
            arr.push(list[i]);
        }
    }
    return arr;
}
// renderFruits(newJson);

//选中后处理数据  
var showClickTextFunction = function (a) {

    //alert(this.innerText + "---" + this.getAttribute("code"));  
    oTxt.value = a;
    // $(‘#ruleOrgCode‘).val(this.getAttribute("code"));
    oList.style.display = "none";
    console.log(oTxt.value);
};
    </script>
</body>
</html>

根据这个简单功能的实现,可以进行一些更加复杂的操作

我现在做的一个模糊查询是根据返回的Json数据来和后台的数据进行匹配

当你输入的值得不到匹配的时候,出现的模糊搜索框会消失

具体思路如下

由于是在当前页面内所有的input标签内

所以

1.先获取所有页面的内input标签

2.设定一个全局变量用来存储对应Json内的数据

3.通过for循环遍历所有的input标签

  3.1每个input标签触发onclick事件

    3.1.1找到当前被点击input标签的id(当前id存储的是Json数据内的键名)

    3.1.2设置两个全局变量用来存储Json树当前节点和父级节点

    3.1.3通过getNode方法(这个方法之前的随笔里有)找到当前节点和父级节点

    3.1.4把当前节点下被模糊查询的数据,也就是一个数组放到第2步设定的全局变量中

  3.2每个input标签 触发keyup事件

    3.2.1设定一个局部变量,用来存储一个返回值;通过创建ul层的方法得到一个返回值确定是否继续往下执行(ul层用来存储对应的数据)

    3.2.2通过if(返回值),当为真,则继续执行

    3.2.3设定一个局部变量获得新创建的ul层的Dom节点,然后给ul层设定样式,比如定位,宽,背景色等等

    3.2.4设定一个局部变量用来获得input标签输入的值

    3.2.5通过方法获取匹配到的电话号码,返回的是一个数组

    3.2.6通过方法输入为空或者匹配到的号码为空则删除电话号码ul层

    3.2.7通过方法把电话号码写在li层,然后添加到ul中

    3.2.8显示被鼠标点击的电话号码

主要javascript代码如下:

fuzzy_Search: function () {
              //先找到对应的属性,然后才能继续执行
              var newJson = this.jsonB.ModuleList;
              //先确定所有的input标签
              var inputLabel = document.getElementsByClassName("wrap")[0].getElementsByTagName("input");
              //存储当前input的下电话号码的数据
              var currentData;
              //遍历所有的input
              for (var i = 0; i < inputLabel.length; i++) {
                  inputLabel[i].onclick = function () {
                      //找到了当前被点击input标签的id
                      var backLabel = show_element(event);
                      console.log(backLabel);
                      //设置Json树当前节点的变量名
                      node = null;
                      //设置Json树父级节点的变量名
                      parentNode = null;
                      //根据获取的id名查找所在当前节点以及父节点的方法
                      var obj = getNode(newJson, backLabel);
                      console.log(obj);;
                      //typeData为被查询数据所在数组对应的键名
                      currentData = obj.node.TypeData;                     
                  }
                  inputLabel[i].addEventListener(‘keyup‘, function () {
                          //创建ul层的函数,通过返回值确定是否继续往下执行
                          var flag = createSearchUl(currentData, this);
                          if (flag) {
                              //获取创建好的ul层的DOM节点
                              var oList = document.getElementById("createUl");
                              //设置ul层的属性
                              oList.setAttribute(‘style‘, ‘position: absolute;left:180px;top:50px;z-index:100;background:#fff;list-style:none;width:71%;cursor:pointer‘);
                              console.log("找到了Ul", oList);
                              //在input标签中获取输入的值
                              var keyWord = this.value;
                              //通过searchByRegExp方法获取匹配到的电话号码,返回的是一个数组
                              var dataList = searchByRegExp(keyWord, currentData);
                              //输入为空或者匹配到的号码为空则删除电话号码ul层
                              checkCharacter(this, oList, dataList);
                              //把电话号码写在li层,然后添加到ul中
                              renderData(dataList, oList);
                              //显示被鼠标点击的电话号码
                              showClickDiv(oList, this);

                          }
                  }, false);

              }
              

              //创建一个ul,然后在input标签对应的父级中添加入ul
              function createSearchUl(CrData, thisLabel) {
                  if (CrData.length > 0) {
                      if (!(thisLabel.value == ‘‘ || thisLabel.value == ‘null‘ || thisLabel.value == undefined)) {
                          //找到input标签的父级
                          var searchDiv = thisLabel.parentNode;
                          //给他的父级做一个相对定位
                          searchDiv.setAttribute(‘style‘, ‘position: relative‘);
                          //建立一个装电话号码的ul
                          var iUl = document.createElement("ul");
                          //把ul添加到父级中
                          searchDiv.appendChild(iUl);
                          //给ul建立一个id
                          searchDiv.getElementsByTagName("ul")[0].setAttribute(‘id‘, ‘createUl‘);

                          return true;

                      } else {
                          
                          var UlS = thisLabel.parentNode.getElementsByTagName("ul");
                              //console.log("当前input标签的父级",thisInput.parentNode);
                              for (var i = UlS.length - 1; i >= 0; i--) {
                                  UlS[0].parentNode.removeChild(UlS[i]);
                              }
                          
                          return false;
                      }
                  }
                  
              }
              //找到被点击元素id的方法
              function show_element(e) {
                  if (!e) {
                      var e = window.event;
                  }
                  //获取事件点击元素  
                  var targ = e.target;
                  //获取元素名称  
                  var tname = targ.id;
                  return tname;
              }
              //根据获取的id名查找所在当前节点以及父节点
              function getNode(json, nodeId) {
                  //1.第一层 root 深度遍历整个JSON
                  for (var i = 0; i < json.length; i++) {
                      console.log(json[i].Content);
                      for (var j = 0; j < json[i].Content.length; j++) {
                          if (node) {
                              break;
                          }
                          var obj = json[i].Content[j];
                          //没有就下一个
                          if (!obj || !obj.FieldName) {
                              continue;
                          }
                          //2.有节点就开始找,一直递归下去
                          if (obj.FieldName == nodeId) {
                              //找到了与nodeId匹配的节点,结束递归
                              node = obj;
                              break;
                          } else {
                              //3.如果有子节点就开始找
                              if (obj.TypeData1) {
                                  //4.递归前,记录当前节点,作为parent 父亲
                                  parentNode = obj;
                                  //递归往下找
                                  getNode(obj.TypeData1, nodeId);
                              } else {
                                  //跳出当前递归,返回上层递归
                                  continue;
                              }
                          }
                      }
                  }
                  //5.如果木有找到父节点,置为null,因为没有父亲  
                  if (!node) {
                      parentNode = null;
                  }
                  //6.返回结果obj
                  return {
                      //父级节点
                      parentNode: parentNode,
                      //当前节点
                      node: node
                  };
              }
              //显示被鼠标点击的电话号码
              function showClickDiv(oList,thisInput) {
                  var liList = oList.getElementsByTagName("li");
                  console.log(liList);
                  for (var i = 0; i < liList.length; i++) {
                      liList[i].onclick = function () {
                          console.log(this.innerHTML);
                          //三个实参;1.当前li标签内的内容,2.输入的值;3.当前的ul层
                          showClickTextFunction(this.innerHTML, thisInput, oList);
                      }
                  }
              }
              //输入为空或者匹配到的号码为空则删除电话号码ul层
              function checkCharacter(thisInput, oList, dataList) {
                  //获取input标签输入的值
                  var etest = thisInput.value;
                  //为空则删除创建的ul层
                  if (etest == ‘‘ || etest == ‘null‘ || etest == undefined) {
                      oList.parentNode.removeChild(oList);
                      return false;
                  }//当再次匹配号码为空,则删除所有的ul层
                  else if (dataList <= 0) {
                      var UlS = thisInput.parentNode.getElementsByTagName("ul");
                      //console.log("当前input标签的父级",thisInput.parentNode);
                      for (var i = UlS.length-1; i >= 0; i--) {
                          oList.parentNode.removeChild(UlS[i]);
                      }
                  }
                  
              }
              //把电话号码写在li层,然后添加到ul中
              function renderData(list, oList) {
                  //传进来的list不是数组,就跳出该方法
                  if (!(list instanceof Array)) {
                      return;
                  }
                  //设置ul的内容为空
                  oList.innerHTML = ‘‘;
                  //获取存电话号码数组的长度
                  var len = list.length;
                  //定义一个变量用来创建li标签
                  var item = null;
                  //for循环遍历存电话号码的数组,把号码写入创建的li标签中,再添加到ul中
                  for (var i = 0; i < len; i++) {
                      item = document.createElement(‘li‘);
                      //为创建的li标签添加class
                      item.setAttribute("class", "newLi"+i);
                      item.innerHTML = list[i];
                      oList.appendChild(item);
                  }
              }
              //正则匹配
              //keyword是输入的值,list是存储数据的数组
              function searchByRegExp(keyWord, list) {
                  if (!(list instanceof Array)) {
                      return;
                  }
                  var len = list.length;
                  var arr = [];
                  var reg = new RegExp(keyWord);
                  for (var i = 0; i < len; i++) {
                      //匹配到一个电话号码就存入数组中
                      if (list[i].phone.match(reg)) {
                          arr.push(list[i].phone);
                      }
                  }
                  return arr;
              }
              //选中后处理数据  
              function showClickTextFunction(a, b, oList) {
                  b.value = a;
                  oList.style.display = "none";
              }


          }

 

以上是关于JavaScript根据Json数据来做的模糊查询功能的主要内容,如果未能解决你的问题,请参考以下文章

Python 代码实现模糊查询

js根据数据关键字实现模糊查询功能

php mysql 分词 模糊查询 并根据分词匹配度排序

django怎么模糊匹配json中的数据?

Sql优化-多like模糊查询及根据时间排序

Mysql模糊查询,按相似度排序