我目前有一个动态下拉菜单,该菜单使用<select>
并将其转换为<ul><li>
。单击任何列表项元素后,它会向项添加一个名为.selected
的类。
我想要实现的目标是什么?一旦您开始将鼠标悬停在列表项上,它应该是<ul>
的一个名为.hovering
的类。
问题:当用户点击document
,window
,点击关闭下拉列表或选择其他下拉列表时,类.hovering
应从{ {1}}。除了用户选择项目时,它都会发生这种情况,它会关闭下拉列表,但不会删除悬停类。
<ul>
var jq = jQuery.noConflict();
(function(jq) {
jq.fn.selectBox = function() {
// Cache the number of options
var sthis = jq(this),
numberOfOptions = jq(this).children('option').length;
// Hides the select element
if (jq('html').hasClass('touch')) {
jq('.options').addClass('s-hidden');
sthis.wrap('<div class="select"></div>');
// Insert a styled div to sit over the top of the hidden select element
sthis.wrap('<div class="styledSelect"></div>');
} else {
sthis.addClass('s-hidden');
// Wrap the select element in a div
sthis.wrap('<div class="select"></div>');
// Insert a styled div to sit over the top of the hidden select element
sthis.after('<div class="styledSelect"></div>');
// Cache the styled div
var styledSelect = sthis.next('div.styledSelect');
// Insert an unordered list after the styled div and also cache the list
var slist = jq('<ul />', {
'class': 'options'
}).insertAfter(styledSelect);
// Insert a list item into the unordered list for each select option
for (var i = 0; i < numberOfOptions; i++) {
jq('<li />', {
text: sthis.children('option').eq(i).text(),
"data-value": sthis.children('option').eq(i).val(),
"class": sthis.children('option').eq(i).attr('class'),
"data-sku": sthis.children('option').eq(i).data('sku'),
"data-stock": sthis.children('option').eq(i).data('stock'),
"data-backorder": sthis.children('option').eq(i).data('backorder'),
"data-preorder": sthis.children('option').eq(i).data('preorder')
}).appendTo(slist);
}
// Cache the list items
var slistItems = slist.children('li');
slistItems.hover(function() {
slist.addClass('hovering');
});
// Show the unordered list when the styled div is clicked (also hides it if the div is clicked again)
styledSelect.click(function(e) {
e.stopPropagation();
var closeClicked = jq(this).hasClass("active");
jq('div.styledSelect.active').each(function() {
slist.removeClass('hovering');
jq(this).removeClass('active').next('ul.options').hide();
});
if (!closeClicked) {
jq(this).toggleClass('active').next('ul.options').toggle();
}
});
// Hides the unordered list when a list item is clicked and updates the styled div to show the selected list item
// Updates the select element to have the value of the equivalent option
slistItems.click(function(e) {
e.stopPropagation();
styledSelect.text(jq(this).text()).removeClass('active');
jq(this).addClass("selected").siblings().removeClass("selected");
sthis.val(jq(this).data('value'));
sthis.addClass('THIS');
slist.removeClass('hovering').hide();
});
// Show the first select option in the styled div
if (sthis.val()) {
var currentSelect = sthis.find("option:selected").val();
styledSelect.text(sthis.find("option:selected").text());
slist.find("li[data-value='" + currentSelect + "']").each(function() {
jq(this).addClass('selected');
slist.removeClass('hovering');
});
} else {
styledSelect.text(sthis.children('option').eq(0).text());
}
// Hides the unordered list when clicking outside of it
jq(document).click(function() {
styledSelect.removeClass('active');
slist.removeClass('hovering').hide();
});
jq('#addtoBag, .wishListBtn').click(function() {
styledSelect.removeClass('active');
slist.removeClass('hovering').hide();
});
}
};
}(jQuery));
jq('.selectBoxStyle').selectBox();
.selectSizeMain {
width: 56.77966%;
float: none;
margin: 2.1875rem auto auto;
}
.s-hidden {
visibility: hidden;
padding-right: 10px;
}
.select {
cursor: pointer;
display: inline-block;
position: relative;
color: black;
font-family: GibsonRegular, HelveticaNeue, Helvetica, sans-serif;
font-size: 14px;
font-size: .875rem;
height: 40px;
width: 100%;
}
.styledSelect {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
padding: 11px 13px;
border: 1px solid #ddd;
background-color: #fff;
}
.styledSelect:after {
content: "";
width: 0;
height: 0;
border: 5px solid transparent;
border-color: black transparent transparent transparent;
position: absolute;
top: 17px;
right: 9px;
}
.styledSelect.active:after {
content: "";
width: 0;
height: 0;
border: 5px solid transparent;
border-color: green transparent transparent transparent;
position: absolute;
top: 17px;
right: 9px;
}
.options {
display: none;
position: absolute;
max-height: 280px;
overflow-y: scroll;
top: 100%;
right: 0;
left: 0;
z-index: 999;
margin: 0 0;
padding: 0 0;
list-style: none;
border: 1px solid #ccc;
border-top: none;
background-color: white;
}
.options li {
padding: 11px 13px;
margin: 0 0;
}
.options li:hover {
background-color: #000;
color: #fff;
}
.options li.selected {
background-color: #000;
color: #fff;
}
答案 0 :(得分:0)
The problem is that you only handled adding the class on mouseenter. But i don't see any method for removing it.
slistItems.hover(function() {
slist.addClass('hovering');
}, function(){
slist.removeClass('hovering');
});
hover()
in jquery is like mouseenter
and mouseleave
combined into one, where the first event is the mouseenter
and the second is mouseleave
. So...
if (jq('html').hasClass('touch')) {
jq('.options').addClass('s-hidden');
sthis.wrap('<div class="select"></div>');
// Insert a styled div to sit over the top of the hidden select element
sthis.wrap('<div class="styledSelect"></div>');
} else {
sthis.addClass('s-hidden');
// Wrap the select element in a div
sthis.wrap('<div class="select"></div>');
// Insert a styled div to sit over the top of the hidden select element
sthis.after('<div class="styledSelect"></div>');
// Cache the styled div
var styledSelect = sthis.next('div.styledSelect');
// Insert an unordered list after the styled div and also cache the list
var slist = jq('<ul />', {
'class': 'options'
}).insertAfter(styledSelect);
// Insert a list item into the unordered list for each select option
for (var i = 0; i < numberOfOptions; i++) {
jq('<li />', {
text: sthis.children('option').eq(i).text(),
"data-value": sthis.children('option').eq(i).val(),
"class": sthis.children('option').eq(i).attr('class'),
"data-sku": sthis.children('option').eq(i).data('sku'),
"data-stock": sthis.children('option').eq(i).data('stock'),
"data-backorder": sthis.children('option').eq(i).data('backorder'),
"data-preorder": sthis.children('option').eq(i).data('preorder')
}).appendTo(slist);
}
// Cache the list items
var slistItems = slist.children('li');
slistItems.hover(function() {
slist.addClass('hovering');
}, function(){
slist.removeClass('hovering');
});
...