带有自定义滚动条 (mCustomScrollbar) 的自定义选择 (Nice select)
Posted
技术标签:
【中文标题】带有自定义滚动条 (mCustomScrollbar) 的自定义选择 (Nice select)【英文标题】:Custom select (Nice select) with custom scrollbar (mCustomScrollbar) 【发布时间】:2019-03-28 02:49:19 【问题描述】:我是新来的,遇到了一个我无法解决的问题。
我有一个使用nice select 的自定义选择,它运行良好,然后我添加了mCustomScrollbar,它也运行良好,问题是当我只想使用键盘时,我首先使用 TAB 然后按下显示选项的向下箭头(或空格键、回车键、向上箭头),一旦您继续使用箭头向下移动,滚动条不会随着光标移动而显示其余选项,例如如果您使用鼠标,我想找到一种解决此问题的方法,以便用户在使用键盘时可以看到所有选项。
Codepen: 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'
);
谢谢!
【问题讨论】:
【参考方案1】:我有同样的任务。我就是这样做的
脚本:
$('.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);
...
【讨论】:
以上是关于带有自定义滚动条 (mCustomScrollbar) 的自定义选择 (Nice select)的主要内容,如果未能解决你的问题,请参考以下文章
带有 css 或 jquery 的自定义滚动条 firefox