【问题标题】:select2 with closeOnSelect false loses scroll position on selectselect2 with closeOnSelect false 在选择时丢失滚动位置
【发布时间】:2016-11-10 05:05:24
【问题描述】:

Select2 版本 4.0.3:在 closeOnSelect 设置为 false 的大型选项列表中使用多选时,我试图从大型列表的中间选择多个选项。每次我选择一个选项时,选择项列表都会滚动回第一个选项。然后我必须向下滚动列表以找到我刚刚选择的选项之后的选项。

有没有办法配置 Select2 在选择特定选项后保留滚动位置?

【问题讨论】:

    标签: jquery jquery-select2


    【解决方案1】:

    出于显而易见的原因,我不建议降级或修改源代码。开发人员已声明此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')))
    

    【讨论】:

    • 感谢您的指点。对于新访客 - 已修复。只需升级到 Select2 4.0.12 版本即可。
    【解决方案2】:

    这是 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 文件

    希望对你有帮助

    【讨论】:

    • 好答案...要注意的一件事是您还希望在“取消选择”事件中执行此操作。
    【解决方案3】:

    看到这条评论后:

    https://github.com/select2/select2/issues/4417#issuecomment-256575280

    我也从 4.0.3 降级到 4.0.2 并且已修复。

    【讨论】:

      【解决方案4】:

      感谢@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')));
      

      【讨论】:

        【解决方案5】:

        在 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);
              ----
              ----
              ---- 
              ----
              ----
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-06-14
          • 2022-12-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多