【发布时间】:2016-11-10 05:05:24
【问题描述】:
Select2 版本 4.0.3:在 closeOnSelect 设置为 false 的大型选项列表中使用多选时,我试图从大型列表的中间选择多个选项。每次我选择一个选项时,选择项列表都会滚动回第一个选项。然后我必须向下滚动列表以找到我刚刚选择的选项之后的选项。
有没有办法配置 Select2 在选择特定选项后保留滚动位置?
【问题讨论】:
标签: jquery jquery-select2
Select2 版本 4.0.3:在 closeOnSelect 设置为 false 的大型选项列表中使用多选时,我试图从大型列表的中间选择多个选项。每次我选择一个选项时,选择项列表都会滚动回第一个选项。然后我必须向下滚动列表以找到我刚刚选择的选项之后的选项。
有没有办法配置 Select2 在选择特定选项后保留滚动位置?
【问题讨论】:
标签: jquery jquery-select2
出于显而易见的原因,我不建议降级或修改源代码。开发人员已声明此problem will be fixed in the upcoming update。
目前,挂钩到“选择”和“选择”事件可以正常工作:
$('select[multiple]').select2({
closeOnSelect: false
})
.on('select2:selecting', e => $(e.currentTarget).data('scrolltop', $('.select2-results__options').scrollTop()))
.on('select2:select', e => $('.select2-results__options').scrollTop($(e.currentTarget).data('scrolltop')))
【讨论】:
这是 select 2 插件的内部问题。
这是添加以下功能后发生的回归, 突出显示第一项();在选项选择事件上
根据链接, https://github.com/select2/select2/issues/4584
对此的解决方法是在执行此函数之前添加以下条件,
if(!(self.options.get('multiple') && !self.options.get('closeOnSelect'))) {
self.highlightFirstItem();
}
所以在选择事件(在 select.js 文件中的第 1036 行)变成, 之前 -
container.on('select', function () {
if (!container.isOpen()) {
return;
}
self.setClasses();
self.highlightFirstItem();
});
之后 -
container.on('select', function () {
if (!container.isOpen()) {
return;
}
self.setClasses();
if(!(self.options.get('multiple') && !self.options.get('closeOnSelect'))){
self.highlightFirstItem();
}
});
所以在突出显示第一个元素之前,即重置滚动到顶部,我们正在验证当前 select2 下拉菜单是否启用了多选并且 closeOnSelect 选项未设置为 false,如果其中任何一个为 true,则突出显示第一个选项不是调用所以滚动保留在选项选择
您必须在 select2.js 库中进行此编辑,因为目前还没有带有此修复的官方 select2 版本。我已使用 select 2 版本 4.0.3 进行编辑。
以下是步骤, 下载 select2 4.0.3 zip,来自 https://github.com/select2/select2/tags
为了缩小源文件(select2.js),在本地安装nodejs。
解压文件夹,进入 dist/js/ 打开select2.js,把上面后面提到的代码中的container.on('select')函数代码替换掉。
对于文件缩小(uglification),select2 使用 grunt, 所以在命令行上打开提取的 select2-4.0.3 文件夹。
运行以下命令, npm 安装 npm install -g grunt-cli 咕噜咕噜的丑化
上面所做的代码更改将移动到 select2-4.0.3/dist/js 文件夹中的 select2.min.js 文件中,您现在可以在项目中将其用作 select2 js 文件
希望对你有帮助
【讨论】:
看到这条评论后:
https://github.com/select2/select2/issues/4417#issuecomment-256575280
我也从 4.0.3 降级到 4.0.2 并且已修复。
【讨论】:
感谢@Fabian von Ellerts,我在 Select2 4.0.3 中使用以下代码解决了这个问题。
$('.select2-multiple').select2({
closeOnSelect : false,
allowHtml: true,
allowClear: true,
tags: true
})
.on('select2:selecting', e => $(e.currentTarget).data('scrolltop', $('.select2-results__options').scrollTop()))
.on('select2:select', e => $('.select2-results__options').scrollTop($(e.currentTarget).data('scrolltop')))
.on('select2:unselecting', e => $(e.currentTarget).data('scrolltop', $('.select2-results__options').scrollTop()))
.on('select2:unselect', e => $('.select2-results__options').scrollTop($(e.currentTarget).data('scrolltop')));
【讨论】:
在 Select2 版本 3.4.8 中,可以通过在第 2933 行注释 this.updateResults() 来解决。有关更多详细信息,请查看以下代码
之前
// multi
onSelect: function (data, options) {
if (!this.triggerSelect(data)) { return; }
this.addSelectedChoice(data);
this.opts.element.trigger({ type: "selected", val: this.id(data), choice: data });
// keep track of the search's value before it gets cleared
this.nextSearchTerm = this.opts.nextSearchTerm(data, this.search.val());
this.clearSearch();
this.updateResults();
if (this.select || !this.opts.closeOnSelect) this.postprocessResults(data, false, this.opts.closeOnSelect===true);
----
----
----
----
----
之后
// multi
onSelect: function (data, options) {
if (!this.triggerSelect(data)) { return; }
this.addSelectedChoice(data);
this.opts.element.trigger({ type: "selected", val: this.id(data), choice: data });
// keep track of the search's value before it gets cleared
this.nextSearchTerm = this.opts.nextSearchTerm(data, this.search.val());
this.clearSearch();
//this.updateResults(); // comment this line to prevent scroll top scroll bar
if (this.select || !this.opts.closeOnSelect) this.postprocessResults(data, false, this.opts.closeOnSelect===true);
----
----
----
----
----
【讨论】: