基于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 相关文章推荐
[Web]防止用户复制页面内容和另存页面的方法
Feb 06 Javascript
javascript中实现兼容JAVA的hashCode算法代码分享
Aug 11 Javascript
再分享70+免费的jquery 图片滑块效果插件和教程
Dec 15 Javascript
AngularJS基础教程之简单介绍
Sep 27 Javascript
jQuery实现简洁的导航菜单效果
Nov 23 Javascript
js实现表单及时验证功能 用户信息立即验证
Sep 13 Javascript
详解vue中computed 和 watch的异同
Jun 30 Javascript
Vue.js简易安装和快速入门(第二课)
Oct 17 Javascript
vue :src 文件路径错误问题的解决方法
May 15 Javascript
在vue中给列表中的奇数行添加class的实现方法
Sep 05 Javascript
微信小程序实现上拉加载功能示例【加载更多数据/触底加载/点击加载更多数据】
May 29 Javascript
Vue3+elementui plus创建项目的方法
Dec 01 Vue.js
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
解析zend Framework如何自动加载类
2013/06/28 PHP
php中删除数组的第一个元素和最后一个元素的函数
2015/03/07 PHP
PHP-FPM之Chroot执行环境详解
2015/08/03 PHP
php将从数据库中获得的数据转换成json格式并输出的方法
2018/08/21 PHP
PHP实现基于3DES算法加密解密字符串示例
2018/08/24 PHP
PHP实现对数字分隔加千分号的方法
2019/03/18 PHP
JavaScript操作XML实例代码(获取新闻标题并分页,并分页)
2010/05/25 Javascript
JavaScript中的isXX系列是否继续使用的分析
2011/04/16 Javascript
JS实现根据当前文字选择返回被选中的文字
2014/05/21 Javascript
js实现模拟银行卡账号输入显示效果
2015/11/18 Javascript
JavaScript面向对象程序设计教程
2016/03/29 Javascript
Bootstrap Table使用方法详解
2016/08/01 Javascript
js控制一个按钮是否可点击(可使用)disabled的实例
2017/02/14 Javascript
JS检测数组类型的方法小结
2017/03/14 Javascript
JS基于正则表达式的替换操作(replace)用法示例
2017/04/28 Javascript
Vue学习笔记进阶篇之单元素过度
2017/07/19 Javascript
基于angular6.0实现的一个组件懒加载功能示例
2018/04/12 Javascript
微信小程序实现倒计时调用相机自动拍照功能
2018/06/10 Javascript
Vuejs2 + Webpack框架里,模拟下载的实例讲解
2018/09/05 Javascript
解决vuex刷新状态初始化的方法实现
2019/08/15 Javascript
利用webpack理解CommonJS和ES Modules的差异区别
2020/06/16 Javascript
解决Vue中使用keepAlive不缓存问题
2020/08/04 Javascript
基于ajax实现上传图片代码示例解析
2020/12/03 Javascript
Python实现压缩和解压缩ZIP文件的方法分析
2017/09/28 Python
浅谈python中对于json写入txt文件的编码问题
2018/06/07 Python
使用Python来开发微信功能
2018/06/13 Python
python如何删除文件中重复的字段
2019/07/16 Python
基于python实现音乐播放器代码实例
2020/07/01 Python
将不规则的Python多维数组拉平到一维的方法实现
2021/01/11 Python
Html5画布_动力节点Java学院整理
2017/07/13 HTML / CSS
介绍一下linux的文件系统
2015/10/06 面试题
致跳远运动员广播稿
2014/02/11 职场文书
师德师风自查总结
2014/10/14 职场文书
使用numpy nonzero 找出非0元素
2021/05/14 Python
如何使用Python提取Chrome浏览器保存的密码
2021/06/09 Python
MySQL中正则表达式(REGEXP)使用详解
2022/07/07 MySQL