正常的下拉列表在拥有1500多个项目时非常快。是否有任何解决这种情况的方法?
使用分页建议,即使在IE8中也可以使其正常工作。
代码:
// Function to shuffle the demo data
function shuffle(str) {
return str
.split('')
.sort(function() {
return 0.5 - Math.random();
})
.join('');
}
// For demonstration purposes we first make
// a huge array of demo data (20 000 items)
// HEADS UP; for the _.map function i use underscore (actually lo-dash) here
function mockData() {
return _.map(_.range(1, 20000), function(i) {
return {
id: i,
text: shuffle('te ststr ing to shuffle') + ' ' + i,
};
});
}
(function() {
// init select 2
$('#test').select2({
data: mockData(),
placeholder: 'search',
multiple: true,
// query with pagination
query: function(q) {
var pageSize,
results,
that = this;
pageSize = 20; // or whatever pagesize
results = [];
if (q.term && q.term !== '') {
// HEADS UP; for the _.filter function i use underscore (actually lo-dash) here
results = _.filter(that.data, function(e) {
return e.text.toUpperCase().indexOf(q.term.toUpperCase()) >= 0;
});
} else if (q.term === '') {
results = that.data;
}
q.callback({
results: results.slice((q.page - 1) * pageSize, q.page * pageSize),
more: results.length >= q.page * pageSize,
});
},
});
})();
这里有一个包含20000个项目的工作示例: http://embed.plnkr.co/db8SXs/preview
由于plnkr嵌入不支持IE8,因此请使用以下链接在IE8上尝试它: http://run.plnkr.co/plunks/db8SXs/
$('#e24').select2('val', ["150"]);
不起作用。 - timetofly$('#e24').val([firstSelectedValue, secondSelectedValue)
并且根据select2文档将initSelection : function (element, callback) { var data = []; $(element.val().split(",")).each(function () { data.push({id: this, text: this}); }); callback(data); },
添加到select2初始化中,那么这是可能的。
但在初始化器内使用val: ["1", "2"]
时我无法使其工作。更新的工作plnkr:http://embed.plnkr.co/db8SXs/preview - MarcusAsplundoptgroup
中进行搜索。 - Maulik Vora我知道这是一个老问题,但我想分享一下对我有用的方法。如果你必须预加载大列表(这可能更容易取决于你是从头开始还是在别人的代码基础上构建),请使用minimumInputLength
,如文档中所述。只有用户输入了几个字符后,才会显示巨大的选项列表。当实际选择Select2下拉列表时,这极大地减少了呈现它们时的性能影响。希望这有所帮助!
closeOnSelect
:false
来允许这样做。如果使用了 minimumInputLength
,用户无法一次选择多个项目,只能一次选择一个。 - Darren Griffith这是Select2 v4的可用版本
基于此处的答案,并进行修改以使搜索与lo-dash配合使用
$(function () {
items = []
for (var i = 0; i < 1000; i++) {
items.push({ id: i, text : "item " + i})
}
pageSize = 50
jQuery.fn.select2.amd.require(["select2/data/array", "select2/utils"],
function (ArrayData, Utils) {
function CustomData($element, options) {
CustomData.__super__.constructor.call(this, $element, options);
}
Utils.Extend(CustomData, ArrayData);
CustomData.prototype.query = function (params, callback) {
var results = [];
if (params.term && params.term !== '') {
results = _.filter(items, function(e) {
return e.text.toUpperCase().indexOf(params.term.toUpperCase()) >= 0;
});
} else {
results = items;
}
if (!("page" in params)) {
params.page = 1;
}
var data = {};
data.results = results.slice((params.page - 1) * pageSize, params.page * pageSize);
data.pagination = {};
data.pagination.more = params.page * pageSize < results.length;
callback(data);
};
$(document).ready(function () {
$("select").select2({
ajax: {},
dataAdapter: CustomData
});
});
})
});
JsFiddle: http://jsfiddle.net/nea053tw/
编辑: Fiddle已更改。
对我来说最简单、最短的方法是:
$(".client_id").select2({
minimumInputLength: 2
});
您可以根据需要更改minimumInputLength的值。
这样,select2就不必显示整个列表,而是仅在输入固定数量的字符后才会带来结果。尽管您仍然在前端代码中拥有大型数组列表。
此外,如果您正在使用allowClear,则必须像这样声明placehodler:
$(".client_id").select2({
minimumInputLength: 2,
allowClear: true,
placeholder: '--Select Client--'
});
请查看这里的文档 http://select2.github.io/select2
如果您的数据仍然太大并且仍然存在性能问题,请使用Ajax方法。最好不要在选择器中加载过多的数据,而是使用Ajax来为Select2加载数据 https://select2.org/data-sources/ajax
<option>
的形式加载超过1500个实际元素到页面上,这可能会影响页面性能。正如一位用户在评论中建议的那样,您可以通过向后端服务发起AJAX调用来解决性能问题,该服务将返回您的值。
Select2 AJAX 如何操作
虽然我们已经有了更新版本的select2,但是如果有人想要在optgroup中进行搜索,可以尝试这个解决方案。
http://jsfiddle.net/na1zLkz3/4/
// Function to shuffle the demo data
var shuffle = function (str) {
return str.split('').sort(function () {
return 0.5 - Math.random();
}).join('');
};
// For demonstration purposes we first make
// a huge array of demo data (20 000 items)
// HEADS UP; for the _.map function i use underscore (actually lo-dash) here
var mockData = function () {
var array = _.map(_.range(1, 10), function (i) {
return {
id : i,
text: shuffle('te ststr ing to shuffle') + ' ' + i
};
});
return array;
};
var mockData1 = function () {
var array = _.map(_.range(10, 15), function (i) {
return {
id : i,
text: shuffle('te ststr ing to shuffle') + ' ' + i
};
});
return array;
};
var mockData2 = function () {
var array = _.map(_.range(15, 20), function (i) {
return {
id : i,
text: shuffle('te ststr ing to shuffle') + ' ' + i
};
});
return array;
};
// create demo data
var dummyData = mockData();
var dummyData1 = mockData1();
var dummyData2 = mockData2();
dummyData.push({
text: 'canada',
children: dummyData1
});
dummyData.push({
text: 'USA',
children: dummyData2
});
// init select 2
$('#ddlCar').select2({
data : dummyData,
// init selected from elements value
initSelection : function (element, callback) {
var initialData = [];
$(element.val().split(",")).each(function () {
initialData.push({
id : this,
text: this
});
});
callback(initialData);
},
// NOT NEEDED: These are just css for the demo data
dropdownCssClass : 'capitalize',
containerCssClass: 'capitalize',
// NOT NEEDED: text for loading more results
formatLoadMore : function() {return 'Loading more...'},
// query with pagination
query : function (q) {
var pageSize,
results;
pageSize = 20; // or whatever pagesize
var results = [];
if (q.term && q.term !== "") {
// HEADS UP; for the _.filter function i use underscore (actually lo-dash) here
var results = this.data;
var results = _.filter(results, function (e) {
if(typeof e.children != 'undefined')
{
subresults = _.filter(e.children, function (f) {
return (f.text.toUpperCase().indexOf(q.term.toUpperCase()) >= 0);
});
if(subresults.length > 0)
return true;
return false;
}
return (e.text.toUpperCase().indexOf(q.term.toUpperCase()) >= 0);
});
newresults = [];
for (var i = 0, len = results.length; i < len; i++) {
newresults[i] = {};
if(typeof results[i].text != 'undefined')
newresults[i].text = results[i].text;
if(typeof results[i].id != 'undefined')
newresults[i].id = results[i].id;
if(typeof results[i].children != 'undefined')
{
newresults[i].children = results[i].children;
newresults[i].children = _.filter(newresults[i].children, function (f) {
return (f.text.toUpperCase().indexOf(q.term.toUpperCase()) >= 0);
});
}
}
results = newresults;
} else if (q.term === "") {
results = this.data;
}
q.callback({
results: results.slice((q.page - 1) * pageSize, q.page * pageSize),
more : results.length >= q.page * pageSize
});
}
});
不幸的是,答案是切换到selectize.js!
lofihelsinki的解决方案适用于<select>
。不幸的是,它不能与<select multiple>
一起使用。
因此,我从select2切换到selectize.js。它在处理大量项目时运行非常快。
这里有一个包含13500多个项目的示例!https://htmlcssjsp.vasilisp.repl.co/selectize-example/
require('select2')
不支持查询参数。需要完整版本require('select2/dist/js/select2.full')
,然后使用此处显示的代码,在select 2 v4中适用于我,data()返回一个包含16k个城市列表。
$(".select_2_cities").select2({
theme: "bootstrap",
data: data(),
multiple: true,
query : function (q) {
var pageSize,
results;
pageSize = 20; // or whatever pagesize
var results = [];
if (q.term && q.term !== "") {
// HEADS UP; for the _.filter function i use underscore (actually lo-dash) here
var results = this.data;
var results = _.filter(results, function (e) {
if(typeof e.children != 'undefined')
{
subresults = _.filter(e.children, function (f) {
return (f.text.toUpperCase().indexOf(q.term.toUpperCase()) >= 0);
});
if(subresults.length > 0)
return true;
return false;
}
return (e.text.toUpperCase().indexOf(q.term.toUpperCase()) >= 0);
});
newresults = [];
for (var i = 0, len = results.length; i < len; i++) {
newresults[i] = {};
if(typeof results[i].text != 'undefined')
newresults[i].text = results[i].text;
if(typeof results[i].id != 'undefined')
newresults[i].id = results[i].id;
if(typeof results[i].children != 'undefined')
{
newresults[i].children = results[i].children;
newresults[i].children = _.filter(newresults[i].children, function (f) {
return (f.text.toUpperCase().indexOf(q.term.toUpperCase()) >= 0);
});
}
}
results = newresults;
} else if (q.term === "") {
results = this.data;
}
q.callback({
results: results.slice((q.page - 1) * pageSize, q.page * pageSize),
more : results.length >= q.page * pageSize
});
}
});