基于JavaScript实现前端数据多条件筛选功能


Posted in Javascript onAugust 19, 2020

有时候也会需要在前端进行数据筛选,增强交互体验。当数据可用的筛选条件较多时,把逻辑写死会给后期维护带来很大麻烦。下面是我自己写的一个简单的筛选器,筛选条件可以根据数据包含的字段动态设置。

仿照京东的筛选条件,这里就取价格区间和品牌作为测试。

基于JavaScript实现前端数据多条件筛选功能

代码

代码中主要使用js的过滤器Array.prototype.filter,该方法会对数组元素进行遍历检查,返回一个符合检查条件的新数组,不会改变原数组。

// filter()
var foo = [0,1,2,3,4,5,6,7,8,9];

var foo1 = foo.filter(
 function(item) {
 return item >= 5
 }
);

console.log(foo1); // [5, 6, 7, 8, 9]

有了这个方法,筛选数据方便了很多,下面先定义一个商品类。

// 定义商品类
function Product(name, brand, price) {
 this.name = name; // 名称
 this.brand = brand; // 品牌
 this.price = price; // 价格
}

创建一个过滤器对象,把所有过滤数据的方法放在里面。为了能自动适配不同的筛选条件,将筛选条件分为两个大类,一个是区间类型rangesFilter ,如:品牌、内存等;一个是选择类型choosesFilter,如:价格、屏幕尺寸等。

不同大类同时筛选时,进行的是与逻辑,每个大类在上一个大类筛选结果上进行筛选。比如我要筛选2000-5000块的华为手机,先调用rangesFilter筛选products并返回结果result1,然后用choosesFilter筛选result1并返回结果resulte2。

当然,如果还有其它大类,不一定是与逻辑,再另行处理。

// 商品筛选器
const ProductFilters = {
 /**
 * 区间类型筛选
 * @param {array<Product>} products
 * @param {array<{type: String, low: number, high: number}>} ranges
 */
 rangesFilter: function (products, ranges) { }

 /**
 * 选择类型筛选
 * @param {array<Product>} products
 * @param {array<{type: String, value: String}>} chooses
 */
 choosesFilter: function (products, chooses) { }
}

区间类型的筛选,代码如下。

// 区间类型条件结构
ranges: [
 {
  type: 'price', // 筛选类型/字段
  low: 3000, // 最小值
  high: 6000 // 最大值
 }
 ]
/**
 * @param {array<Product>} products
 * @param {array<{type: String, low: number, high: number}>} ranges
 */
 rangesFilter: function (products, ranges) {
 if (ranges.length === 0) {
  return products;
 } else {
  /**
  * 循环多个区间条件,
  * 每种区间类型应该只有一个,
  * 比如价格区间不会有1000-2000和4000-6000同时需要的情况
  */
  for (let range of ranges) {
  // 多个不同类型区间是与逻辑,可以直接赋值给自身
  products = products.filter(function (item) {
   return item[range.type] >= range.low && item[range.type] <= range.high;
  });
  }
  return products;
 }
 }

选择类型筛选:

// 选择类型条件结构
chooses: [
 {
  type: 'brand',
  value: '华为'
 },
 {
  type: 'brand',
  value: '苹果'
 }
 ]
/**
 * @param {array<Product>} products
 * @param {array<{type: String, value: String}>} chooses
 */
 choosesFilter: function (products, chooses) {
 let tmpProducts = [];
 if (chooses.length === 0) {
  tmpProducts = products;
 } else {
  /**
  * 选择类型条件是或逻辑,使用数组连接concat
  */
  for (let choice of chooses) {
  tmpProducts = tmpProducts.concat(products.filter(function (item) {
   return item[choice.type].indexOf(choice.value) !== -1;
  }));
  }
 }
 return tmpProducts;
 }

定义一个执行函数doFilter()。

function doFilter(products, conditions) {
 // 根据条件循环调用筛选器里的方法
 for (key in conditions) {
 // 判断是否有需要的过滤方法
 if (ProductFilters.hasOwnProperty(key + 'Filter') && typeof ProductFilters[key + 'Filter'] === 'function') {
  products = ProductFilters[key + 'Filter'](products, Conditions[key]);
 }
 }
 return products;
}
// 将两种大类的筛选条件放在同一个对象里
let Conditions = {
 ranges: [
 {
  type: 'price',
  low: 3000,
  high: 6000
 }
 ],
 chooses: [
 {
  type: 'brand',
  value: '华为'
 }
 ]
}

测试

创建10个商品数据,以及筛选条件

// 商品数组
const products = [
 new Product('华为荣耀9', '华为', 2299),
 new Product('华为P10', '华为', 3488),
 new Product('小米MIX2', '小米', 3599),
 new Product('小米6', '小米', 2499),
 new Product('小米Note3', '小米', 2499),
 new Product('iPhone7 32G', '苹果', 4588),
 new Product('iPhone7 Plus 128G', '苹果', 6388),
 new Product('iPhone8', '苹果', 5888),
 new Product('三星Galaxy S8', '三星', 5688),
 new Product('三星Galaxy S7 edge', '三星', 3399),
];
// 筛选条件
let Conditions = {
 ranges: [
 {
  type: 'price',
  low: 3000,
  high: 6000
 }
 ],
 chooses: [
 {
  type: 'brand',
  value: '华为'
 },
 {
  type: 'brand',
  value: '苹果'
 }
 ]
}

调用函数

let result = doFilter(products, Conditions);
console.log(result);

输出

基于JavaScript实现前端数据多条件筛选功能

代码的扩展性和可维护性都很好,只要保证筛选条件中的type字段在商品数据中一致都可以筛选,比如将筛选条件改为

let Conditions = {
 ranges: [
 {
  type: 'price',
  low: 3000,
  high: 6000
 }
 ],
 chooses: [
 {
  type: 'name',
  value: 'iPhone'
 }
 ]
}

输出

基于JavaScript实现前端数据多条件筛选功能

搜索匹配等一些地方也需要优化,是否区分大小写、是完全匹配还是模糊匹配等。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
jQuery获得IE版本不准确webbrowser的解决方法
Feb 23 Javascript
JS获得图片alt信息的方法
Apr 01 Javascript
fastclick插件导致日期(input[type=&quot;date&quot;])控件无法被触发该如何解决
Nov 09 Javascript
Highcharts入门之简介
Aug 02 Javascript
jQuery如何跳转到另一个网页 就这么简单
Dec 28 Javascript
vue mint-ui学习笔记之picker的使用
Oct 11 Javascript
在vue中封装可复用的组件方法
Mar 01 Javascript
Vue.js 通过jQuery ajax获取数据实现更新后重新渲染页面的方法
Aug 09 jQuery
jQuery中each和js中forEach的区别分析
Feb 27 jQuery
Element-ui中元素滚动时el-option超出元素区域的问题
May 30 Javascript
layui监听单元格编辑前后交互的例子
Sep 16 Javascript
微信小程序中data-key属性之数据传输(经验总结)
Aug 22 Javascript
javascript 开发之网页兼容各种浏览器
Sep 28 #Javascript
JavaScript中重名的函数与对象示例详析
Sep 28 #Javascript
js 开发之autocomplete=&quot;off&quot;在chrom中失效的解决办法
Sep 28 #Javascript
微信小程序下拉刷新界面的实现
Sep 28 #Javascript
详解Vuex中mapState的具体用法
Sep 28 #Javascript
Node.js学习之地址解析模块URL的使用详解
Sep 28 #Javascript
javascript基于牛顿迭代法实现求浮点数的平方根【递归原理】
Sep 28 #Javascript
You might like
Windows中安装Apache2和PHP4权威指南
2006/11/18 PHP
PHP上传文件时文件过大$_FILES为空的解决方法
2013/11/26 PHP
PHP获取音频文件的相关信息
2015/06/22 PHP
基于PHP实现短信验证码接口(容联运通讯)
2016/09/06 PHP
表头固定(利用jquery实现原理介绍)
2012/11/08 Javascript
jquery滚动条插件jScrollPane的使用介绍
2013/11/08 Javascript
Js Jquery创建一个弹出层可加载一个页面
2014/05/08 Javascript
jQuery.lazyload+masonry改良图片瀑布流代码
2014/06/20 Javascript
Javascript中实现trim()函数的两种方法
2015/02/04 Javascript
JS实现FLASH幻灯片图片切换效果的方法
2015/03/04 Javascript
理解jquery事件冒泡
2016/01/03 Javascript
jQuery获取checkbox选中的值
2016/01/28 Javascript
javascript如何定义对象数组
2016/06/07 Javascript
vue.js之vue-cli脚手架的搭建详解
2017/05/05 Javascript
微信小程序loading组件显示载入动画用法示例【附源码下载】
2017/12/09 Javascript
layui table 表格上添加日期控件的两种方法
2019/09/28 Javascript
浅谈vue 锚点指令v-anchor的使用
2019/11/13 Javascript
Vue Elenent实现表格相同数据列合并
2020/11/30 Vue.js
vue-cli中实现响应式布局的方法
2021/03/02 Vue.js
javascript实现倒计时提示框
2021/03/02 Javascript
Django使用AJAX调用自己写的API接口的方法
2019/03/06 Python
pandas 数据结构之Series的使用方法
2019/06/21 Python
python 并发编程 阻塞IO模型原理解析
2019/08/20 Python
python 如何快速复制序列
2020/09/07 Python
python之语音识别speech模块
2020/09/09 Python
python mongo 向数据中的数组类型新增数据操作
2020/12/05 Python
介绍一下#error预处理
2015/09/25 面试题
《搭石》教学反思
2014/04/07 职场文书
学历公证书范本
2014/04/09 职场文书
小学生个人先进事迹材料
2014/05/08 职场文书
销售行政专员岗位职责
2014/06/10 职场文书
学生逃课检讨书1000字
2014/10/20 职场文书
《弟子规》读后感:知廉耻、明是非、懂荣辱、辨善恶
2019/12/03 职场文书
jdbc使用PreparedStatement批量插入数据的方法
2021/04/27 MySQL
在项目中使用redis做缓存的一些思路
2021/09/14 Redis
世界十大儿童漫画书排名,法国国宝漫画排第五,第二是轰动日本连环
2022/03/18 欧美动漫