基于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 相关文章推荐
IE浏览器PNG图片透明效果代码
Sep 02 Javascript
用js模拟JQuery的show与hide动画函数代码
Sep 20 Javascript
jQuery的运行机制和设计理念分析
Apr 05 Javascript
js实现addClass,removeClass,hasClass的函数代码
Jul 13 Javascript
js判断两个日期是否相等的方法
Sep 10 Javascript
javascript实现网页子页面遍历回调的方法(涉及 window.frames、递归函数、函数上下文)
Jul 27 Javascript
Bootstrap优化站点资源、响应式图片、传送带使用详解3
Oct 14 Javascript
利用JS实现文字的聚合动画效果
Jan 22 Javascript
jquery dialog获取焦点的方法
Feb 09 Javascript
webstorm添加vue.js支持的方法教程
Jul 05 Javascript
图片文字识别(OCR)插件Ocrad.js教程
Nov 26 Javascript
微信小程序如何获取地址
Dec 24 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页面编码的两种方法示例介绍
2014/03/03 PHP
一个简单的PHP验证码实现代码
2014/05/10 PHP
php结合正则获取字符串中数字
2015/06/19 PHP
php数据访问之增删改查操作
2016/05/09 PHP
PHP+MySQL实现模糊查询员工信息功能示例
2018/06/01 PHP
javascript获取web应用根目录的方法
2014/02/12 Javascript
SeaJS入门教程系列之完整示例(三)
2014/03/03 Javascript
jquery通过visible来判断标签是否显示或隐藏
2014/05/08 Javascript
javascript继承机制实例详解
2014/11/20 Javascript
JavaScript结合AJAX_stream实现流式显示
2015/01/08 Javascript
基于HTML模板和JSON数据的JavaScript交互(移动端)
2016/04/06 Javascript
JS实现获取剪贴板内容的方法
2016/06/21 Javascript
原生js代码实现图片放大境效果
2016/10/30 Javascript
VUE + UEditor 单图片跨域上传功能的实现方法
2018/02/08 Javascript
React实现全局组件的Toast轻提示效果
2018/09/21 Javascript
详解vue中使用protobuf踩坑记
2019/05/07 Javascript
js实现无缝轮播图特效
2020/05/09 Javascript
JS如何生成动态列表
2020/09/22 Javascript
[52:06]FNATIC vs NIP 2019国际邀请赛小组赛 BO2 第二场 8.16
2019/08/19 DOTA
pandas 数据结构之Series的使用方法
2019/06/21 Python
Django使用中间键实现csrf认证详解
2019/07/22 Python
Python自动生成代码 使用tkinter图形化操作并生成代码框架
2019/09/18 Python
python制作朋友圈九宫格图片
2019/11/03 Python
解释一下ArrayList Vector和LinkedList的实现和区别
2013/04/26 面试题
写自荐信的七个技巧
2013/10/15 职场文书
运动会广播稿200米
2014/01/27 职场文书
管理部副部长岗位职责范文
2014/03/09 职场文书
母校寄语大全
2014/04/10 职场文书
领导干部整治奢华浪费之风思想汇报
2014/10/07 职场文书
销售员未完成销售业绩的检讨书
2014/10/12 职场文书
简历自荐信范文
2015/03/09 职场文书
2015教师年度考核评语
2015/03/25 职场文书
JS Object构造函数之Object.freeze
2021/04/28 Javascript
一文搞懂python异常处理、模块与包
2021/06/26 Python
Nginx虚拟主机的搭建的实现步骤
2022/01/18 Servers
td 内容自动换行 table表格td设置宽度后文字太多自动换行
2022/12/24 HTML / CSS