javascript - 带有自定义滚动条(mCustomScrollbar)的自定义选择(Nice select)

标签 javascript jquery html css mcustomscrollbar

我是新来的,我遇到了一个我无法解决的问题。

我有一个使用 nice select 的自定义选择效果很好,然后我添加了 mCustomScrollbar这也很好用,问题是当我只想使用键盘时,我首先使用 TAB 集中注意力,然后在显示选项的地方按向下箭头(或空格键、回车键、向上箭头) ,一旦您继续使用箭头向下移动,滚动条就不会随着光标移动而显示其余选项,就像您使用鼠标一样,我想找到一种解决此问题的方法,以便当用户使用键盘时它可以看到所有选项。

代码笔: https://codepen.io/anon/pen/MPPybJ

HTML

<section class="form-container">
  <form action="" method="" class="tn-general" novalidate>
    <fieldset>
      <div class="row">
        <div class="col-md-5">
          <div class="form-group form-group-floating-label">
            <div class="custom-select">
              <select required>
                <option value="" disabled selected="selected" hidden>Seleccionar</option>
                <option value="1">Soltero</option>
                <option value="2">Casado</option>
                <option value="3">Divorciado</option>
                <option value="4">Viudo</option>
                <option value="5">Concubino</option>
                <option value="">Casado 1</option>
                <option value="">Casado 2</option>
                <option value="">Casado 3</option>
                <option value="">Casado 4</option>
                <option value="">Casado 5</option>
                <option value="">Casado 6</option>
                <option value="">Casado 7</option>
                <option value="">Casado 8</option>
                <option value="">Casado 9</option>
                <option value="">Casado 10</option>
                <option value="">Casado 11</option>
                <option value="">Casado 12</option>
                <option value="">Casado 13</option>
                <option value="">Casado 14</option>
                <option value="">Casado 15</option>
                <option value="">Casado 16</option>
                <option value="">Casado 17</option>
                <option value="">Casado 18</option>
                <option value="">Casado 19</option>
                <option value="">Casado 20</option>
              </select>
            </div>
          </div>
        </div>      
      </div>
    </fieldset>
  </form>
</section>

CSS

/* Font Size*/
$font-size-small: 0.8em; /*12px*/
$font-size-minismall: 0.813em; /*13px*/
$font-size-normal: 0.9em; /* 14px */
$font-size-main-mininormal: 0.938em; /* 15px */
$font-size-main-normal: 1em; /* 16px */
$font-size-smedium: 1.115em; /* 17px */
$font-size-medium: 1.125em; /* 18px */
$font-size-xmedium: 1.25em; /* 20px */
$font-size-xm-medium: 1.375em; /* 22px */
$font-size-big: 1.5em; /*24px*/
$font-size-xbig: 1.65em; /* 26px */
$font-size-mxlarge: 1.9em; /* 30px */
$font-size-mxxlarge: 2em; /* 32px */
$font-size-mxxxlarge: 2.125em; /* 34px */
$font-size-xlarge: 2.5em; /* 40px */
$font-size-large: 2.75em; /*44px*/
$font-size-xxlarge: 3em; /*48px*/
$font-size-xxxlarge: 50px; /* 50px */
$font-size-ultralarge: 3.75em; /* 60px */
/* Font Type*/
$font-type: "opensans-regular";
$font-type-light: "opensans-light";
$font-type-semibold: "opensans-semibold";
$font-type-bold: "opensans-bold";
$font-type-2: "urwgeometric-regular";
$font-type-2-light: "urwgeometric-light";
$font-type-2-thin: "urwgeometric-thin";
$font-type-2-semibold: "urwgeometric-semibold";
$font-type-2-bold: "urwgeometric-bold";

$color-white: #ffffff;
$color-black: #000000;
/* Gray Color*/
$color-gray: #eeeeee;
$color-gray-1:#C8C8C8;
$color-message-gray: #999fa5;
$color-soft-gray: #aeaeae;
$color-soft-gray-2: #f3f3f3;
$color-soft-gray-3: #c1c1c1;
$color-soft-gray-4: #aaa;
$color-soft-gray-5: #777777;
$color-soft-gray-6: #969696;
$color-soft-gray-7: #f9f9f9;
$color-soft-gray-8: #dddddd;
$color-soft-gray-9: #f0f0f0;
$color-soft-gray-10: #e3e3e3;
$color-dark-gray: #666666;
$color-dark-gray-0: #333333;
$color-dark-gray-2: #434343;
$color-dark-gray-3: #535353;
$color-dark-gray-4: #626262;
$color-dark-gray-5: #d4d4d4;
$color-dark-gray-5: #c9c9c9;
$color-dark-gray-6: #a6a6a6;
$color-dark-gray-7: #555555;
$color-dark-gray-8: #303030;
$color-dark-gray-9:#d8d8d8;
/* Orange Color*/
$color-soft-orange: #f9a885;
$color-super-soft-orange: #FFF8E4;
$color-ui-orange: #ff6600;
$color-ui-orange-2: #ff5a00;
$color-ui-orange-3: #FF6800;
$color-orange: #f56122;
$color-orange-2:#ef5816;
$color-orange-3:#ed5927;
$color-orange-3: #ff7022;
$color-orange-4: #ff5d00;
$color-orange-5: #ef5411;
$color-orange-6:#ff8b1d;
$color-orange-7:#ff8400;
$color-orange-8: #FFA500;
$color-dark-orange: #da480a;
/* Red Color*/
$color-red: #e14421;
$color-red-2: #de0000;
$color-red-3 :#ff6464;
/* Blue Color*/
$color-blue: #3F525F;
$color-dark-blue: #2c4854;
/* Green Color*/
$color-green: #009a63;
$color-green-2: #009900;
$color-green-3: #00d095;
/*Yellow Colors*/
$color-soft-yellow: #fcf8e3;
$color-soft-yellow-2: #fff5d8;
$color-yellow-1: #ffbf00;
$color-yellow-2: #fad054;
/*Gradient Class Colors*/
.tn-gradient-1 {
    background-image: linear-gradient(119deg, #ff6600,#ffcb00);
}

.tn-general {
  .custom-checkbox {
    .custom-control-indicator {
      border-radius: 50%;
      border: 0.15rem solid $color-soft-gray-3;
      background-color: white;
      width: 1.5rem;
      height: 1.5rem;
    }
    .custom-control-description {
      padding-top: 5px;
      padding-left: 10px;
    }
    .custom-control-input:checked~.custom-control-indicator {
      color: white;
      background-color: $color-ui-orange;
      border-color: $color-ui-orange;
      background-size: 10px;
    }
    .custom-control-input:focus ~ .custom-control-indicator {
      box-shadow: 0 0 0 1px #fff, 0 0 0 3px #fff;
    }
  }
  .custom-checkbox-nobg {
    .custom-control-indicator {
      border-radius: 25%;
      border: 0.05rem solid $color-soft-gray;
      background-color: white;
      width: 1.5rem;
      height: 1.5rem;
    }
    .custom-control-description {
      padding-top: 5px;
      padding-left: 10px;
    }
    .custom-control-input:checked ~ .custom-control-indicator {
      color: $color-dark-gray;
      background-color: white;
      border-color: $color-dark-gray;
      background-size: 10px;
      background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%23666' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3E%3C/svg%3E");
    }
    .custom-control-input:focus ~ .custom-control-indicator {
      box-shadow: 0 0 0 1px #fff, 0 0 0 3px #fff;
    }
  }
  .tn-btn-main {
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
    cursor: pointer;
    background-color: $color-orange-3;
    border-radius: 50px;
    border: 0;
    color: white;
    font-family: $font-type-semibold;
    font-size: $font-size-main-normal;
    line-height: 1;
    text-align: center;
    width: 200px;
    height: 42px;
    padding: 0;
    margin: 20px 0;
    display: inline-block;
    vertical-align: middle;
    transform: perspective(1px) translateZ(0);
    box-shadow: 0 0 1px transparent;
    overflow: hidden;
    transition-duration: 0.3s;
    transition-property: color, background-color;
    &.tn-mt-3 {
      margin-top: 30px;
    }
    &:hover {
      background-color: $color-orange-7;
    }
    &:focus {
      outline: 0;
    }
    &.disabled {
      opacity: 0.6;
      color: $color-dark-gray-7;
      cursor: default;
      font-family: "opensans-regular";
    }
  }
  .tn-btn-msg {
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
    cursor: pointer;
    background-color: $color-ui-orange-3;
    border-radius: 5px;
    border: 0;
    color: white;
    font-family: $font-type-semibold;
    font-size: $font-size-medium;
    line-height: 1;
    padding: 10px 15px;
    margin: 5px 0;
    display: inline-block;
    vertical-align: middle;
    transform: perspective(1px) translateZ(0);
    box-shadow: 0 0 1px transparent;
    overflow: hidden;
    transition-duration: 0.3s;
    transition-property: color, background-color;
    &.tn-mt-3 {
      margin-top: 30px;
    }
    &:hover {
      background-color: $color-orange-7;
    }
    &:focus {
      outline: 0;
    }
    &.disabled {
      opacity: 0.6;
      color: $color-dark-gray-7;
      cursor: default;
      font-family: "opensans-regular";
    }
  }
  .tn-btn-second {
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
    cursor: pointer;
    background-color: $color-white;
    border: 2px solid $color-ui-orange;
    border-radius: 50px;
    color: $color-ui-orange;
    font-family: $font-type-semibold;
    font-size: $font-size-main-normal;
    line-height: 1;
    width: 200px;
    height: 42px;
    padding: 0;
    text-align: center;
    margin: 20px 0;
    display: inline-block;
    vertical-align: middle;
    transform: perspective(1px) translateZ(0);
    box-shadow: 0 0 1px transparent;
    overflow: hidden;
    transition-duration: 0.3s;
    transition-property: color, background-color;
    &.tn-mt-3 {
      margin-top: 30px;
    }
    &:hover {
      border: 2px solid $color-orange-7;
      background-color: $color-white;
      color: $color-orange-7;
    }
    &:focus {
      outline: 0;
    }
    &.disabled {
      opacity: 0.6;
      color: $color-dark-gray-7;
      cursor: default;
      font-family: "opensans-regular";
    }
  }
  .tn-btn-collapse {
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
    color: $color-orange-5;
    font-size: $font-size-normal;
    font-family: $font-type-semibold;
    background-color: $color-soft-gray-9;
    width: 100%;
    border: 0 none;
    padding: 0.8rem;
    position: relative;
    &:before {
      outline: 0;
      display: inline-block;
      content: "";
      background: url("../images/buttons/tn-arrow-collapse.png") center center no-repeat;
      height: 12px;
      width: 12px;
      position: relative;
      top: 2px;
      right: 5px;
    }
    &:focus {
      outline: 0;
      box-shadow: none;
    }
  }
  .tn-btn-collapse[aria-expanded="true"] {
    &:before {
      background: url("../images/buttons/tn-arrow-collapsed.png") no-repeat;
    }
  }
  /* Black Check */
  .check-icon {
    list-style-type: none;
    li {
      background: url("../images/icons/check-small-2.png") no-repeat 0 4px;
      padding-left: 20px;
      margin: 5px 0;
      font-family: $font-type;
      line-height: 1;
      color: $color-dark-gray;
    }
  }
  .tn-form-wrapper {
    p {
      margin-bottom: 0;
    }
  }
  .tn-form-title {
    h1 {
      color: $color-dark-gray-8;
      font-family: $font-type;
      font-weight: bold;
      font-size: $font-size-mxxxlarge;
      padding-bottom: 15px;
    }
  }
  // Floating labels
  .form-group.form-group-floating-label {
    position: relative;
    &:not(:first-child) {
      margin-top: 40px;
    }
    label {
      font-size: 15px;
      font-weight: 600;
      color: $color-soft-gray-4;
      display: block;
    }
    .form-control {
      font-family: 'urwgeometric-regular';
      font-size: $font-size-xmedium;
      font-weight: 600;
      color: $color-dark-gray-0;
      width: 100%;
      border: 0;
      border-bottom: 1px solid #CCC;
      border-radius: 0;
      padding-top: 0;
      padding-left: 0;
      outline: 0;
      &.invalid {
        border-color: $color-red-2;
      }
      &:focus {
        border-color: $color-ui-orange;
      }
      &:focus + .form-control-placeholder,
      &:valid + .form-control-placeholder {
        font-size: $font-size-main-normal;
        transform: translate3d(0, -100%, 0);
      }
      &:disabled + .form-control-placeholder {
        font-size: $font-size-main-normal;
        transform: translate3d(0, -100%, 0);
      }
      &:disabled + .form-control-placeholder.form-control-placeholder-no-input {
        transform: none;
      }
      &:disabled {
        background-color: transparent;
        cursor: not-allowed;
        border-color: $color-soft-gray-10;
      }
    }
    .form-control-placeholder {
      font-size: $font-size-xmedium;
      font-weight: 600;
      color: $color-soft-gray-4;
      position: absolute;
      top: 0;
      left: 0;
      padding-top: 5px;
      transition: all 200ms;
      cursor: text;
    }
    .form-invalid-message {
      font-size: $font-size-normal;
      font-weight: 600;
      color: $color-red-2;
      max-width: 100%;
      margin-top: 4px;
      margin-bottom: 0;
      position: absolute;

      &.position-relative {
        position: relative;
      }
    }
    &.form-group-single-inputs {
      input {
        display: inline-block;
        height: 24px;
        font-size: $font-size-xbig;
        text-align: center;
        max-width: 20px;
        padding: 0;
        margin-top: 17px;
        margin-right: 7px;
        vertical-align: bottom;
        &:valid {
          border-color: transparent;
        }
        &:invalid {
          border-color: #CCC;
        }
        &:focus {
          border-color: $color-ui-orange;
        }
        &.invalid {
          border-color: $color-red-2;
        }
      }
    }
    // custom select dropdown
    select {
      display: none;
    }
    .custom-select {
      display: block;
      background: transparent;
      border: 0;
      padding: 6px 0;
      position: relative;
        .nice-select {
          font-family: 'urwgeometric-regular';
          font-size: $font-size-xmedium;
          font-weight: 600;
          color: $color-dark-gray-0;
          background: url('../../Content/images/buttons/chevron-down-arrow-light-gray.png') no-repeat right;
          background-size: 15px;
          border-bottom: 1px solid #CCC;
          padding-bottom: 7px;
          cursor: pointer;
          &:focus {
            outline-width: 2px;
            outline-style: solid;
            outline-color: Highlight;
          }
          &:active,
          &:hover,
          &.removeFocus {
            outline: none;
          }
          & span.current {
            color: $color-soft-gray-4;
          }
          &.open {
            border-color: $color-ui-orange;
            .list {
              opacity: 1;
              pointer-events: auto;
              transform: scale(1) translateY(0);
            }
          }
          &.invalid {
            border-color: $color-red-2;
          }
          &.disabled {
            border-color: $color-soft-gray-10;
            pointer-events: none;
            & span {
              color: $color-soft-gray-10;
            }
          }
          &.optionSelected {
            background: url('../../Content/images/buttons/chevron-down-arrow-dark-gray.png') no-repeat right;
            background-size: 15px;
            & span.current {
              color: $color-dark-gray-0;
            }
          }
          // List and options
          .list {
            max-height: 400px;
            font-size: $font-size-medium;
            font-weight: 600;
            background-color: white;
            color: $color-dark-gray-0;
            position: absolute;
            top: 100%;
            left: 0;
            right: 0;
            z-index: 1;
            margin-top: 8px;
            border: 1px solid #e5e5e5;
            border-radius: 6px;
            box-shadow: 0 5px 10px 0 rgba(0, 0, 0, 0.1);
            opacity: 0;
            pointer-events: none;
            overflow: hidden;

            transition: all .2s cubic-bezier(0.5, 0, 0, 1.25), opacity .15s ease-out;
            &:hover .option:not(:hover):not(.selected) {
              background-color: transparent;
            }
          }
          .option {
            font-weight: bold;
            font-size: 18px;
            height: 70px;
            padding: 0 20px;
            display: flex;
            align-items: center;
            cursor: pointer;
            outline: none;
            transition: all 0.2s;
            &:hover,
            &.focus,
            &.selected.focus {
              background-color: $color-gray;
            }
            &.selected {
              background-color: $color-gray;
            }
            &.disabled {
              display: none;
            }
          }
        }
      }
    // Input checkbox
    .form-input-checkbox {
      // Remove the original ones
      .styled-checkbox {
        position: absolute;
        opacity: 0;
        // Checbox label
        & + label {
          display: inline;
          position: relative;
          padding: 0;
          cursor: pointer;
          // Add styled chexbox
          &:before {
            content: '';
            display: inline-block;
            width: 22px;
            height: 22px;
            background: white;
            vertical-align: text-bottom;
            margin-right: 18px;
            border: 2px solid $color-dark-gray-0;
            border-radius: 4px;
          }
        }
        // Box checked
        &:checked + label:before {
          content: '';
          background: url('../../Content/images/icons/select-checkbox-checked.png') no-repeat right;
          background-size: contain;
          border: 0;
          border-radius: 0;
        }
      }
    }
    .custom-radio {
      & .custom-control-label {
        cursor: pointer;
        margin-bottom: 0;
        &::before {
          content: '';
          border-radius: 50%;
          display: inline-block;
          width: 24px;
          height: 24px;
          pointer-events: none;
          -webkit-user-select: none;
          -moz-user-select: none;
          -ms-user-select: none;
          user-select: none;
          background: url('../../Content/images/icons/radio-button-unselected.svg') center center no-repeat;
          vertical-align: top;
          cursor: pointer;
          margin-right: 10px;
        }
        &::after {
          content: '';
          display: block;
          width: 24px;
          height: 24px;
          background-repeat: no-repeat;
          background-position: center center;
          background-size: 50% 50%;
          position: absolute;
          top: 0;
        }
      }
      & .custom-control-input:not(:checked):focus ~ .custom-control-label::before {
        outline-width: 2px;
        outline-style: solid;
        outline-color: Highlight;
      }
      & .custom-control-input:checked ~ .custom-control-label::before {
        background: url('../../Content/images/icons/radio-button-selected.svg') center center no-repeat;
      }
      & .custom-control-input:checked ~ .custom-control-label::after {
        background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3E%3Ccircle r='3' fill='%23fff'/%3E%3C/svg%3E");
      }
    }
    // input[type="radio"] {
    //   & + label span {
    //     display: inline-block;
    //     width: 24px;
    //     height: 24px;
    //     vertical-align: top;
    //     background: url('../../Content/images/icons/radio-button-unselected.svg') center center no-repeat;
    //     cursor: pointer;
    //     margin-right: 10px;
    //   }
    //
    //   &:checked + label span {
    //     background: url('../../Content/images/icons/radio-button-selected.svg') center center no-repeat;
    //   }
    // }
  }
  // General errors
  .general-invalid-data {
    font-size: 15px;
    font-weight: 600;
    line-height: 1;
    color: $color-red-2;
  }
  // Remove box-shadow from inputs with type text
  input[type="text"] {
    box-shadow: none;
  }
}

JS

// initialize custom select

$('select').niceSelect();

// add outline only when using TAB
let niceSelect = $('.nice-select');

niceSelect.on('click', function()
{
    $(this).addClass('removeFocus');
});

niceSelect.on('blur', function()
{
    if($(this).hasClass('removeFocus'))
    {
        $(this).removeClass('removeFocus');
    }
});

// add class when choosing an option

$('.list .option:not(.disabled)').on('click keypress', function()
{
    $(this).closest('.nice-select').addClass('optionSelected');
});

// remove mCustomScrollbar tabindex

setTimeout(() => {
    $('.mCustomScrollBox').prop('tabindex', '-1');
}, 1000);

$('.nice-select .list').mCustomScrollbar({
    theme: 'minimal-dark'
});

谢谢!

最佳答案

我有同样的任务。我是这样做的

脚本:

$('.jsNiceSelect').niceSelect();

$(document).on('mouseenter', '.nice-select .mCSB_scrollTools', function(event) {
  var $dropdown = $(this).parents('.nice-select');
  $dropdown.addClass('open_scroll');
});
$(document).on('click.nice_select', function(event) {
  if ($(event.target).closest('.nice-select').length === 0) {
    $('.nice-select').removeClass('open_scroll');
    setTimeout(function() { $('.nice-select').removeClass('open'); }, 50);
  }
});
$(document).on('click.nice_select', '.nice-select .option:not(.disabled)', function(event) {
  $('.nice-select').removeClass('open_scroll open');
  setTimeout(function() { $('.nice-select').removeClass('open'); }, 50);
});

CSS:

...
&.open {
 here standard styles nice select
}

here add this:

&.open_scroll{
z-index: 4;
&:after {
  -webkit-transform: rotate(180deg);
  -ms-transform: rotate(180deg);
  transform: rotate(180deg);
}
.list {
  opacity: 1;
  pointer-events: auto;
  -webkit-transform: scale(1) translateY(0);
  -ms-transform: scale(1) translateY(0);
  transform: scale(1) translateY(0);
 }
}
...

关于javascript - 带有自定义滚动条(mCustomScrollbar)的自定义选择(Nice select),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52956265/

相关文章:

javascript - 寻找链接 AJAX 调用的模式

javascript - webpackJsonp 未定义 - VueJS

php - 将 PHP 转换为 JavaScript。将键/值存储到数组中

javascript - 从 https 网站发送请求

javascript - 为什么 CSS 选择器返回一个元素数组?

javascript - 在 event.preventDefault() 之后在 iOS Safari 上手动捏合缩放事件处理;

javascript - 影响 JavaScript for 循环中的对象

html - 带阴影的 CSS 三 Angular 形

javascript - 重现色彩效果

java - 服务未识别 RestAssured 内容类型应用程序/json