最近遇到了一個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 }) },