基于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 相关文章推荐
准确获得页面、窗口高度及宽度的JS
Nov 26 Javascript
JS input 数字验证代码
Jul 30 Javascript
JavaScript 原型继承之构造函数继承
Aug 26 Javascript
javascript里使用php代码实例
Dec 13 Javascript
js简单的点击返回顶部效果实现方法
Apr 10 Javascript
AngularJs  Creating Services详解及示例代码
Sep 02 Javascript
mvc 、bootstrap 结合分布式图简单实现分页
Oct 10 Javascript
js时间戳与日期格式之间相互转换
Dec 11 Javascript
jQuery代码优化方法总结
Jan 29 jQuery
JavaScript实现获取两个排序数组的中位数算法示例
Feb 26 Javascript
vue实现菜单切换功能
May 08 Javascript
javascript实现动态时钟的启动和停止
Jul 29 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
PHP 学习路线与时间表
2010/02/21 PHP
求PHP数组最大值,最小值的代码
2011/10/31 PHP
深入extjs与php参数交互的详解
2013/06/25 PHP
ThinkPHP3.1数据CURD操作快速入门
2014/06/19 PHP
laravel框架如何设置公共头和公共尾
2019/10/22 PHP
javascript showModalDialog模态对话框使用说明
2009/12/31 Javascript
javascript利用初始化数据装配模版的实现代码
2010/11/17 Javascript
javascript-表格排序(降序/反序)实现介绍(附图)
2013/05/30 Javascript
JavaScript对表格或元素按文本,数字或日期排序的方法
2015/05/26 Javascript
JavaScript中数组继承的简单示例
2015/07/29 Javascript
jQuery ui实现动感的圆角渐变网站导航菜单效果代码
2015/08/26 Javascript
Java Mybatis框架入门基础教程
2015/09/21 Javascript
JavaScript判断手机号运营商是移动、联通、电信还是其他(代码简单)
2015/09/25 Javascript
理解Angular数据双向绑定
2016/01/10 Javascript
巧用jQuery选择器提高写表单效率的方法
2016/08/19 Javascript
vue父组件通过props如何向子组件传递方法详解
2017/08/16 Javascript
JS交互点击WKWebView中的图片实现预览效果
2018/01/05 Javascript
js和jQuery以及easyui实现对下拉框的指定赋值方法
2018/01/23 jQuery
vue+webpack实现异步加载三种用法示例详解
2018/04/24 Javascript
基于JS判断对象是否是数组
2020/01/10 Javascript
Python对文件和目录进行操作的方法(file对象/os/os.path/shutil 模块)
2017/05/08 Python
Python内置函数——__import__ 的使用方法
2017/11/24 Python
python3获取两个日期之间所有日期,以及比较大小的实例
2018/04/08 Python
pandas series序列转化为星期几的实例
2018/04/11 Python
Python过滤txt文件内重复内容的方法
2018/10/21 Python
Python Django 封装分页成通用的模块详解
2019/08/21 Python
调整Jupyter notebook的启动目录操作
2020/04/10 Python
html5配合css3实现带提示文字的输入框(摆脱js)
2013/03/08 HTML / CSS
ghd法国官方网站:英国最受欢迎的美发工具品牌
2019/04/18 全球购物
DeinDesign德国:设计自己的手机壳
2019/12/14 全球购物
怎样创建、运行java程序
2014/08/01 面试题
网络技术支持面试题
2013/04/22 面试题
金融行业职业生涯规划范文
2014/01/17 职场文书
推广普通话标语
2014/06/27 职场文书
个人作风建设剖析材料
2014/10/11 职场文书
nginx对http请求处理的各个阶段详析
2021/03/31 Servers