基于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 相关文章推荐
CSS和Javascript简单复习资料
Jun 29 Javascript
js中top、clientTop、scrollTop、offsetTop的区别 文字详细说明版
Jan 08 Javascript
Jquery进度条插件 Progress Bar小问题解决
Jul 12 Javascript
浅谈jQuery异步对象(XMLHttpRequest)
Nov 17 Javascript
谈谈对JavaScript原生拖放的深入理解
Sep 20 Javascript
javascript 判断一个对象为数组的方法
May 03 Javascript
微信小程序中post方法与get方法的封装
Sep 26 Javascript
微信小程序 网络通信实现详解
Jul 23 Javascript
通过实例了解JS 连续赋值
Sep 24 Javascript
JavaScript实现背景自动切换小案例
Sep 27 Javascript
JS数组进阶示例【数组的几种函数用法】
Jan 16 Javascript
微信小程序实现抖音播放效果的实例代码
Apr 11 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
CodeIgniter集成smarty的方法详解
2016/05/26 PHP
jquery validate.js表单验证的基本用法入门
2010/05/13 Javascript
ExtJS 下拉多选框lovcombo
2010/05/19 Javascript
基于Asp.net与Javascript控制的日期控件
2010/05/22 Javascript
基于jquery实现的表格分页实现代码
2011/06/21 Javascript
js获取键盘按键响应事件(兼容各浏览器)
2013/05/16 Javascript
js+div实现图片滚动效果代码
2014/02/10 Javascript
JavaScript模块随意拖动示例代码
2014/05/27 Javascript
js实现鼠标悬停图片上时滚动文字说明的方法
2015/02/17 Javascript
nodejs创建web服务器之hello world程序
2015/08/20 NodeJs
JS实现三个层重叠点击互相切换的方法
2015/10/06 Javascript
javascript 数组的定义和数组的长度
2016/06/07 Javascript
javascript的replace方法结合正则使用实例总结
2016/06/16 Javascript
原生javascript实现图片放大镜效果
2017/01/18 Javascript
jQuery validate 验证radio实例
2017/03/01 Javascript
vue2.0实战之基础入门(1)
2017/03/27 Javascript
Angular客户端请求Rest服务跨域问题的解决方法
2017/09/19 Javascript
浅谈node的事件机制
2017/10/09 Javascript
详解vue指令与$nextTick 操作DOM的不同之处
2018/08/02 Javascript
值得收藏的八个常用的js正则表达式
2018/10/19 Javascript
基于Vue.js与WordPress Rest API构建单页应用详解
2019/09/16 Javascript
[00:30]塑造者的传承礼包-戴泽“暗影之焰”套装展示视频
2014/04/04 DOTA
用pywin32实现windows模拟鼠标及键盘动作
2014/04/22 Python
python 每天如何定时启动爬虫任务(实现方法分享)
2018/05/21 Python
Python遍历字典方式就实例详解
2019/12/28 Python
Python字符编码转码之GBK,UTF8互转
2020/02/09 Python
Python3爬虫关于识别点触点选验证码的实例讲解
2020/07/30 Python
Pygame框架实现飞机大战
2020/08/07 Python
Python读取图像并显示灰度图的实现
2020/12/01 Python
工程部经理岗位职责
2013/12/08 职场文书
国际贸易专业个人求职信格式
2014/02/02 职场文书
四年级科学教学反思
2014/02/10 职场文书
法人委托书范本格式
2014/09/15 职场文书
2014年外贸业务员工作总结
2014/12/11 职场文书
MySQL Innodb索引机制详细介绍
2021/11/23 MySQL
SQL SERVER实现连接与合并查询
2022/02/24 SQL Server