最近遇到了一个select2的问题,所以把解决方法记录下来
问题:
1:单个Select2控件加载大量数据时会发生页面卡顿问题
2:在使用select2自带的查询功能会导致页面卡死
解决方案
1:采用分页加载的方式,单次加载的数量过多会导致页面加载速度缓慢,所以将数据分为多次加载
网址:https://select2.org/data-sources/ajax
但是由于业务要求的问题,这种方式不可行
2:改写select2源码
当面临单个select2数据量过大时,select2的搜索功能会导致页面卡死,因为每次输入一个值都会去遍历所有的option值,那要做的就是当用户中断输入后才执行查询操作
源代码与修改后的代码如下
文件:select2.min.js
源码:
b.prototype.handleSearch = function() { if (!this._keyUpPrevented) { var a = this.$search.val(); this.trigger("query", { term: a }) } this._keyUpPrevented = !1 },
更改后:
/**
* 新增一个定时事件,每0.25秒执行一次,这段代码每当用户输入时都会执行,那么如果前一次的输入离后一次的输入在0.25秒之内,定时事件就会被清空并且重新设置
*/
b.prototype.handleSearch = function() { var tagst=this; clearTimeout(tagw); tagw=setTimeout(function(){ if (!window._keyUpPrevented) { var a = tagst.$search.val(); tagst.trigger("query", { term: a }) }},250); this._keyUpPrevented = !1 },
在更改之后查询的频率减少,但是如果数据量多页面依然会卡顿,可以减少select2单次加载的option数量
源码:每次查询都会将所有的结果全部加载
d.prototype.query = function(a, b) { var d = [], e = this, f = this.$element.children(); f.each(function() { var b = c(this); if (b.is("option") || b.is("optgroup")) { var f = e.item(b), g = e.matches(a, f); null !== g && d.push(g) } }), b({ results: d }) },
更改后:一次加载50条
d.prototype.query = function(a, b) { var d = [], dNum=0, e = this, f = this.$element.children(); f.each(function() { if(dNum>50){ return; } var b = c(this); if (b.is("option") || b.is("optgroup")) { var f = e.item(b), g = e.matches(a, f); if(null !== g){ dNum++; d.push(g) } } }), b({ results: d }) },