基于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可突破windows弹退效果代码
Aug 09 Javascript
让AJAX不依赖后端接口实现方案
Dec 03 Javascript
利用Keydown事件阻止用户输入实现代码
Mar 11 Javascript
javascript字母大小写转换的4个函数详解
May 09 Javascript
$(document).ready(function() {})不执行初始化脚本
Jun 19 Javascript
JavaScript中有关一个数组中最大值和最小值及它们的下表的输出的解决办法
Jul 01 Javascript
基于jQuery实现Tabs选项卡自定义插件
Nov 21 Javascript
vue组件如何被其他项目引用
Apr 13 Javascript
完美解决浏览器跨域的几种方法(汇总)
May 08 Javascript
详解Angular2表单-模板驱动的表单(Template-Driven Forms)
Aug 04 Javascript
小程序二次贝塞尔曲线实现购物车商品曲线飞入效果
Jan 07 Javascript
利用Vconsole和Fillder进行移动端抓包调试方法
Mar 05 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横向重复区域显示二法
2008/09/25 PHP
PHP 事务处理数据实现代码
2010/05/13 PHP
PHP中的cookie不用刷新就生效的方法
2012/02/04 PHP
php操作xml
2013/10/27 PHP
ThinkPHP快速入门实例教程之数据分页
2014/07/01 PHP
php中的curl_multi系列函数使用例子
2014/07/29 PHP
phpword插件导出word文件时中文乱码问题处理方案
2014/08/19 PHP
Yii框架关联查询with用法分析
2014/12/02 PHP
layui框架实现文件上传及TP3.2.3(thinkPHP)对上传文件进行后台处理操作示例
2018/05/12 PHP
php curl操作API接口类完整示例
2019/05/21 PHP
用JavaScript 处理 URL 的两个函数代码
2007/08/13 Javascript
jquery png 透明解决方案(推荐)
2010/08/21 Javascript
jQuery中的val()示例应用
2014/02/26 Javascript
Js实现滚动变色的文字效果
2014/06/16 Javascript
使用jQuery.wechat构建微信WEB应用
2014/10/09 Javascript
JavaScript获取客户端IP的方法(新方法)
2016/03/11 Javascript
总结Javascript中的隐式类型转换
2016/08/24 Javascript
Javascript 严格模式use strict详解
2017/09/16 Javascript
对angularJs中自定义指令replace的属性详解
2018/10/09 Javascript
js仿360开机效果
2019/12/26 Javascript
Python处理RSS、ATOM模块FEEDPARSER介绍
2015/02/18 Python
Python3.4 tkinter,PIL图片转换
2018/06/21 Python
selenium+python 对输入框的输入处理方法
2018/10/11 Python
opencv python统计及绘制直方图的方法
2019/01/21 Python
详解如何用python实现一个简单下载器的服务端和客户端
2019/10/28 Python
详解Django配置JWT认证方式
2020/05/09 Python
Python requests HTTP验证登录实现流程
2020/11/05 Python
英国第一蛋白粉品牌:Myprotein
2016/09/14 全球购物
Wojas罗马尼亚网站:波兰皮鞋品牌
2018/11/01 全球购物
医大实习自我鉴定
2013/12/07 职场文书
电子银行营销方案
2014/02/22 职场文书
诚信考试倡议书
2014/04/15 职场文书
习近平在党的群众路线教育实践活动总结大会上的讲话
2014/10/21 职场文书
初中班主任心得体会
2016/01/07 职场文书
SpringCloud之@FeignClient()注解的使用方式
2021/09/25 Java/Android
go goth封装第三方认证库示例详解
2022/08/14 Golang