首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >防止select2向上翻转下拉列表

防止select2向上翻转下拉列表
EN

Stack Overflow用户
提问于 2013-11-14 16:53:21
回答 7查看 45.3K关注 0票数 28

根据标题,是否有办法强迫select2总是创建下拉列表而不是下拉列表?

这里似乎也有一些javascript,当您在下拉菜单上方滚动,添加一个新的CSS类“select2 2-下拉”,或者两者兼而有之,就会导致翻转。

编辑:我应该指定我是通过select2-rails把库拉进来的。我希望有一种解决这个问题的方法,不需要自己拉出整个select2库并直接编辑select2.js文件。

EN

回答 7

Stack Overflow用户

回答已采纳

发布于 2014-06-26 15:34:56

正如您提到的,修改插件是不可取的。我也遇到了类似的问题,无法找到一种方法来使用select2选项来强制下拉列表保持在下面。我得到的解决方案如下:

代码语言:javascript
复制
$("#mySelect2").select2({ ...options... })
    .on('select2-open', function() {

        // however much room you determine you need to prevent jumping
        var requireHeight = 600;
        var viewportBottom = $(window).scrollTop() + $(window).height();

        // figure out if we need to make changes
        if (viewportBottom < requireHeight) 
        {           
            // determine how much padding we should add (via marginBottom)
            var marginBottom = requireHeight - viewportBottom;

            // adding padding so we can scroll down
            $(".aLwrElmntOrCntntWrppr").css("marginBottom", marginBottom + "px");

            // animate to just above the select2, now with plenty of room below
            $('html, body').animate({
                scrollTop: $("#mySelect2").offset().top - 10
            }, 1000);
        }
    });

此代码确定是否有足够的空间将下拉列表放置在底部,如果没有,则通过向页面上的某个元素添加页边距-底部来创建它。然后滚动到select2的上方,这样下拉列表就不会翻转。

票数 3
EN

Stack Overflow用户

发布于 2017-12-20 19:13:30

由于修改源代码不是一个选项,而且向select2:open事件添加钩子也不是很优雅,特别是当您在同一个页面中有多个select2实例时,我已经为Select2插件编写了一个小扩展。

我的实现灵感来自尚未合并的插件存储库(https://github.com/select2/select2/pull/4618)的PR。

基本上,下面的代码覆盖了处理下拉定位的原始插件函数,并添加了一个新选项(dropdownPosition)强制下拉定位在上面/下面。

新的dropdownPosition选项可以采用以下值:- below -下拉列表总是显示在输入的底部;- above -下拉列表总是显示在输入的顶部;- auto (默认)-它使用旧的行为。

只需在select2.js文件之后插入以下代码:

代码语言:javascript
复制
(function($) {

  var Defaults = $.fn.select2.amd.require('select2/defaults');

  $.extend(Defaults.defaults, {
    dropdownPosition: 'auto'
  });

  var AttachBody = $.fn.select2.amd.require('select2/dropdown/attachBody');

  var _positionDropdown = AttachBody.prototype._positionDropdown;

  AttachBody.prototype._positionDropdown = function() {

    var $window = $(window);

    var isCurrentlyAbove = this.$dropdown.hasClass('select2-dropdown--above');
    var isCurrentlyBelow = this.$dropdown.hasClass('select2-dropdown--below');

    var newDirection = null;

    var offset = this.$container.offset();

    offset.bottom = offset.top + this.$container.outerHeight(false);

    var container = {
        height: this.$container.outerHeight(false)
    };

    container.top = offset.top;
    container.bottom = offset.top + container.height;

    var dropdown = {
      height: this.$dropdown.outerHeight(false)
    };

    var viewport = {
      top: $window.scrollTop(),
      bottom: $window.scrollTop() + $window.height()
    };

    var enoughRoomAbove = viewport.top < (offset.top - dropdown.height);
    var enoughRoomBelow = viewport.bottom > (offset.bottom + dropdown.height);

    var css = {
      left: offset.left,
      top: container.bottom
    };

    // Determine what the parent element is to use for calciulating the offset
    var $offsetParent = this.$dropdownParent;

    // For statically positoned elements, we need to get the element
    // that is determining the offset
    if ($offsetParent.css('position') === 'static') {
      $offsetParent = $offsetParent.offsetParent();
    }

    var parentOffset = $offsetParent.offset();

    css.top -= parentOffset.top
    css.left -= parentOffset.left;

    var dropdownPositionOption = this.options.get('dropdownPosition');

    if (dropdownPositionOption === 'above' || dropdownPositionOption === 'below') {
      newDirection = dropdownPositionOption;
    } else {

      if (!isCurrentlyAbove && !isCurrentlyBelow) {
        newDirection = 'below';
      }

      if (!enoughRoomBelow && enoughRoomAbove && !isCurrentlyAbove) {
        newDirection = 'above';
      } else if (!enoughRoomAbove && enoughRoomBelow && isCurrentlyAbove) {
        newDirection = 'below';
      }

    }

    if (newDirection == 'above' ||
    (isCurrentlyAbove && newDirection !== 'below')) {
        css.top = container.top - parentOffset.top - dropdown.height;
    }

    if (newDirection != null) {
      this.$dropdown
        .removeClass('select2-dropdown--below select2-dropdown--above')
        .addClass('select2-dropdown--' + newDirection);
      this.$container
        .removeClass('select2-container--below select2-container--above')
        .addClass('select2-container--' + newDirection);
    }

    this.$dropdownContainer.css(css);

  };

})(window.jQuery);

初始化插件如下所示:

代码语言:javascript
复制
$(document).ready(function() {
  $(".select-el").select2({
    dropdownPosition: 'below'
  });
});

小提琴:https://jsfiddle.net/byxj73ov/

Github存储库:https://github.com/andreivictor/select2-dropdownPosition

更新2019年12月30日

修改最新的Select2版本(v4.0.12):https://jsfiddle.net/g4maj9ox/

票数 35
EN

Stack Overflow用户

发布于 2013-11-14 17:13:08

您只需编辑select2.js

上面写着

代码语言:javascript
复制
enoughRoomBelow = dropTop + dropHeight <= viewportBottom,
enoughRoomAbove = (offset.top - dropHeight) >= this.body().scrollTop(),

只要把它改成

代码语言:javascript
复制
enoughRoomBelow = true,
enoughRoomAbove = false,
票数 29
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19983601

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档