如何将滑块与其他复选框过滤器放在一起
Posted
技术标签:
【中文标题】如何将滑块与其他复选框过滤器放在一起【英文标题】:How to put Slider together with additional checkbox filter 【发布时间】:2018-08-16 15:33:11 【问题描述】:我在使用 Ui 滑块和复选框过滤器时遇到问题。它应该像这样工作:
当我使用滑块设置价格目标时,我得到了一些结果。然后希望这些结果通过使用复选框的附加过滤器进行排序。毕竟我应该得到完全符合我的要求。
而不是我得到了错误的匹配。使用滑块后,我得到了我想要的,但是当使用复选框时,一切都崩溃了。我只得到复选框结果,没有滑块效果。我不知道如何强迫他们一起工作。
如果仅使用滑块(不单击复选框),我还想查看有关找到结果数量的信息。
这是 jsfiddle 示例:http://jsfiddle.net/m1z930r5/15/
html:
<input type="text" id="amount" readonly>
<div class="slider" id="price"></div>
<br><br>
<div class="tabela-wrap">
<label style="number"><input type="checkbox" name="fl-1" value="1" id="1" /> 1</label>
<label style="number"><input type="checkbox" name="fl-2" value="2" id="2" /> 2</label>
<label style="number"><input type="checkbox" name="fl-3" value="3" id="3" /> 3</label>
<label style="number"><input type="checkbox" name="fl-4" value="4" id="4" /> 4</label>
<label style="number"><input type="checkbox" name="fl-5" value="5" id="5" /> 5</label>
<label style="number"><input type="checkbox" name="fl-6" value="6" id="6" /> 6</label>
<label style="number"><input type="checkbox" name="fl-7" value="7" id="7" /> 7</label>
<label style="number"><input type="checkbox" name="fl-8" value="8" id="8" /> 8</label>
</div>
<br><br>
<ul class="tabela lokata" id="products">
<li class="tabelki" data-price="10000" data-category="1 2 3 4 ">10 000 USD contains 1 2 3 4</li>
<li class="tabelki" data-price="12000" data-category="2 3">12 000 USD contains 2 3</li>
<li class="tabelki" data-price="13000" data-category="4 5">13 000 USD contains 4 5</li>
<li class="tabelki" data-price="14000" data-category="5 6 ">14 000 USD contains 5 6</li>
<li class="tabelki" data-price="12000" data-category="5">12 000 USD contains 5</li>
<li class="tabelki" data-price="14000" data-category="1 2">14 000 USD contains 1 2</li>
<li class="tabelki" data-price="16000" data-category="1 2 3">16 000 USD contains 1 2 3</li>
<li class="tabelki" data-price="20000" data-category="7 8">20 000 USD contains 7 8</li>
</ul>
<div class="tabela-wrap">
<label id="found"></label>
</div>
CSS:
.ui-slider
position: relative;
text-align: left;
.ui-slider .ui-slider-handle
position: absolute;
z-index: 2;
width: 1.2em;
height: 1.2em;
cursor: default;
.ui-slider .ui-slider-range
position: absolute;
z-index: 1;
font-size: .7em;
display: block;
border: 0;
background-position: 0 0;
.ui-slider-horizontal
height: .8em;
.ui-slider-horizontal .ui-slider-handle
top: -0.5em;
margin-left: -.6em;
.ui-slider-horizontal .ui-slider-range
top: 0;
height: 100%;
.ui-slider-horizontal .ui-slider-range-min
left: 0;
.ui-slider-horizontal .ui-slider-range-max
right: 0;
.ui-slider-vertical
width: .8em;
height: 100px;
.ui-slider-vertical .ui-slider-handle
left: -.3em;
margin-left: 0;
margin-bottom: -.6em;
.ui-slider-vertical .ui-slider-range
left: 0;
width: 100%;
.ui-slider-vertical .ui-slider-range-min
bottom: 0;
.ui-slider-vertical .ui-slider-range-max
top: 0;
.ui-widget-content
border: 1px solid #aaaaaa;
background: white 50% 50% repeat-x;
color: #222222;
.ui-widget
font-family: Verdana, Arial, sans-serif;
font-size: 1.1em;
.ui-state-default,
.ui-widget-content .ui-state-default,
.ui-widget-header .ui-state-default
width: 30px;
height: 30px;
border: 3px solid #2F3D44;
border-radius: 20px;
background: white 50% 50% repeat-x;
font-weight: normal;
color: #555555;
.slider1Hide
display: none;
! function(a)
function f(a, b)
if (!(a.originalEvent.touches.length > 1))
a.preventDefault();
var c = a.originalEvent.changedTouches[0],
d = document.createEvent("MouseEvents");
d.initMouseEvent(b, !0, !0, window, 1, c.screenX, c.screenY, c.clientX, c.clientY, !1, !1, !1, !1, 0, null), a.target.dispatchEvent(d)
if (a.support.touch = "ontouchend" in document, a.support.touch)
var e, b = a.ui.mouse.prototype,
c = b._mouseInit,
d = b._mouseDestroy;
b._touchStart = function(a)
var b = this;
!e && b._mouseCapture(a.originalEvent.changedTouches[0]) && (e = !0, b._touchMoved = !1, f(a, "mouseover"), f(a, "mousemove"), f(a, "mousedown"))
, b._touchMove = function(a)
e && (this._touchMoved = !0, f(a, "mousemove"))
, b._touchEnd = function(a)
e && (f(a, "mouseup"), f(a, "mouseout"), this._touchMoved || f(a, "click"), e = !1)
, b._mouseInit = function()
var b = this;
b.element.bind(
touchstart: a.proxy(b, "_touchStart"),
touchmove: a.proxy(b, "_touchMove"),
touchend: a.proxy(b, "_touchEnd")
), c.call(b)
, b._mouseDestroy = function()
var b = this;
b.element.unbind(
touchstart: a.proxy(b, "_touchStart"),
touchmove: a.proxy(b, "_touchMove"),
touchend: a.proxy(b, "_touchEnd")
), d.call(b)
(jQuery);
// Added this function
function data_filter(mini, maxi, data_name)
$("#products li").filter(function()
var value = parseInt($(this).data(data_name), 10);
if (value > maxi || value < mini)
$(this).addClass('slider1Hide');
);
function showProducts()
// Reset filters
$("#products li").removeClass('slider1Hide');
// Price
var minP = $("#price").slider("values", 0);
var maxP = $("#price").slider("values", 1);
data_filter(minP, maxP, "price"); // Call the new function
$(function()
var options =
min: 500,
max: 100000,
step: 500,
values: [10000],
slide: function(event, ui)
$("#amount").val(ui.values[0] + " USD");
,
change: function(event, ui)
showProducts();
;
$("#price").slider(options);
$("#amount").val($("#price").slider("values", 0) + " USD");
);
//Checkboxes script
var byProperty = [],
byColor = [],
byLocation = [];
$("input[name=fl-1]").on("change", function()
if (this.checked) byProperty.push("[data-category~='" + $(this).attr("value") + "']");
else removeA(byProperty, "[data-category~='" + $(this).attr("value") + "']");
);
$("input[name=fl-2]").on("change", function()
if (this.checked) byProperty.push("[data-category~='" + $(this).attr("value") + "']");
else removeA(byProperty, "[data-category~='" + $(this).attr("value") + "']");
);
$("input[name=fl-3]").on("change", function()
if (this.checked) byProperty.push("[data-category~='" + $(this).attr("value") + "']");
else removeA(byProperty, "[data-category~='" + $(this).attr("value") + "']");
);
$("input[name=fl-4]").on("change", function()
if (this.checked) byProperty.push("[data-category~='" + $(this).attr("value") + "']");
else removeA(byProperty, "[data-category~='" + $(this).attr("value") + "']");
);
$("input[name=fl-5]").on("change", function()
if (this.checked) byProperty.push("[data-category~='" + $(this).attr("value") + "']");
else removeA(byProperty, "[data-category~='" + $(this).attr("value") + "']");
);
$("input[name=fl-6]").on("change", function()
if (this.checked) byProperty.push("[data-category~='" + $(this).attr("value") + "']");
else removeA(byProperty, "[data-category~='" + $(this).attr("value") + "']");
);
$("input[name=fl-7]").on("change", function()
if (this.checked) byProperty.push("[data-category~='" + $(this).attr("value") + "']");
else removeA(byProperty, "[data-category~='" + $(this).attr("value") + "']");
);
$("input[name=fl-8]").on("change", function()
if (this.checked) byProperty.push("[data-category~='" + $(this).attr("value") + "']");
else removeA(byProperty, "[data-category~='" + $(this).attr("value") + "']");
);
$("input").on("change", function()
var str = "Include items \n";
var selector = '',
cselector = '',
nselector = '';
var $lis = $('.tabela > li'),
$checked = $('input:checked');
if ($checked.length)
if (byProperty.length)
if (str == "Include items \n")
str += " " + "with (" + byProperty.join(',') + ")\n";
$($('input[name=fl-1]:checked')).each(function(index, byProperty)
if (selector === '')
selector += "[data-category~='" + byProperty.id + "']";
else
selector += ",[data-category~='" + byProperty.id + "']";
);
else
str += " AND " + "with (" + byProperty.join(' OR ') + ")\n";
$($('input[name=fl-1]:checked')).each(function(index, byProperty)
selector += "[data-category~='" + byProperty.id + "']";
);
if (byProperty.length)
if (str == "Include items \n")
str += " " + "with (" + byProperty.join(',') + ")\n";
$($('input[name=fl-2]:checked')).each(function(index, byProperty)
if (selector === '')
selector += "[data-category~='" + byProperty.id + "']";
else
selector += ",[data-category~='" + byProperty.id + "']";
);
else
str += " AND " + "with (" + byProperty.join(' OR ') + ")\n";
$($('input[name=fl-2]:checked')).each(function(index, byProperty)
selector += "[data-category~='" + byProperty.id + "']";
);
if (byProperty.length)
if (str == "Include items \n")
str += " " + "with (" + byProperty.join(',') + ")\n";
$($('input[name=fl-3]:checked')).each(function(index, byProperty)
if (selector === '')
selector += "[data-category~='" + byProperty.id + "']";
else
selector += ",[data-category~='" + byProperty.id + "']";
);
else
str += " AND " + "with (" + byProperty.join(' OR ') + ")\n";
$($('input[name=fl-3]:checked')).each(function(index, byProperty)
selector += "[data-category~='" + byProperty.id + "']";
);
if (byProperty.length)
if (str == "Include items \n")
str += " " + "with (" + byProperty.join(',') + ")\n";
$($('input[name=fl-4]:checked')).each(function(index, byProperty)
if (selector === '')
selector += "[data-category~='" + byProperty.id + "']";
else
selector += ",[data-category~='" + byProperty.id + "']";
);
else
str += " AND " + "with (" + byProperty.join(' OR ') + ")\n";
$($('input[name=fl-4]:checked')).each(function(index, byProperty)
selector += "[data-category~='" + byProperty.id + "']";
);
if (byProperty.length)
if (str == "Include items \n")
str += " " + "with (" + byProperty.join(',') + ")\n";
$($('input[name=fl-5]:checked')).each(function(index, byProperty)
if (selector === '')
selector += "[data-category~='" + byProperty.id + "']";
else
selector += ",[data-category~='" + byProperty.id + "']";
);
else
str += " AND " + "with (" + byProperty.join(' OR ') + ")\n";
$($('input[name=fl-5]:checked')).each(function(index, byProperty)
selector += "[data-category~='" + byProperty.id + "']";
);
if (byProperty.length)
if (str == "Include items \n")
str += " " + "with (" + byProperty.join(',') + ")\n";
$($('input[name=fl-6]:checked')).each(function(index, byProperty)
if (selector === '')
selector += "[data-category~='" + byProperty.id + "']";
else
selector += ",[data-category~='" + byProperty.id + "']";
);
else
str += " AND " + "with (" + byProperty.join(' OR ') + ")\n";
$($('input[name=fl-6]:checked')).each(function(index, byProperty)
selector += "[data-category~='" + byProperty.id + "']";
);
if (byProperty.length)
if (str == "Include items \n")
str += " " + "with (" + byProperty.join(',') + ")\n";
$($('input[name=fl-7]:checked')).each(function(index, byProperty)
if (selector === '')
selector += "[data-category~='" + byProperty.id + "']";
else
selector += ",[data-category~='" + byProperty.id + "']";
);
else
str += " AND " + "with (" + byProperty.join(' OR ') + ")\n";
$($('input[name=fl-7]:checked')).each(function(index, byProperty)
selector += "[data-category~='" + byProperty.id + "']";
);
if (byProperty.length)
if (str == "Include items \n")
str += " " + "with (" + byProperty.join(',') + ")\n";
$($('input[name=fl-8]:checked')).each(function(index, byProperty)
if (selector === '')
selector += "[data-category~='" + byProperty.id + "']";
else
selector += ",[data-category~='" + byProperty.id + "']";
);
else
str += " AND " + "with (" + byProperty.join(' OR ') + ")\n";
$($('input[name=fl-8]:checked')).each(function(index, byProperty)
selector += "[data-category~='" + byProperty.id + "']";
);
$lis.hide();
console.log(selector);
console.log(cselector);
console.log(nselector);
if (cselector === '' && nselector === '')
$('.tabela > li').filter(selector).show();
else if (cselector === '')
$('.tabela > li').filter(selector).filter(nselector).show();
else if (nselector === '')
$('.tabela > li').filter(selector).filter(cselector).show();
else
$('.tabela > li').filter(selector).filter(cselector).filter(nselector).show();
else
$lis.show();
$("#result").html(str);
);
$("input").on("change", function()
var numberOfItems = $("li.tabelki:visible").length;
if (numberOfItems > 0)
var label = "We found " + numberOfItems + " results";
else
var label = "No results found";
$("#found").text(label);
);
function removeA(arr)
var what, a = arguments,
L = a.length,
ax;
while (L > 1 && arr.length)
what = a[--L];
while ((ax = arr.indexOf(what)) !== -1)
arr.splice(ax, 1);
return arr;
有人能解决这个案子吗?
【问题讨论】:
【参考方案1】:试试这个:
我对您的代码进行了很多重构,以使其更易于阅读/理解并保持干燥。我能够将行数从 273 行减少到 73 行。
$(document).ready(function()
// cache ref to all checkbox elements
var checkboxes = $('input:checkbox'),
// cache ref to results
results = $('#results'),
// cache ref to our list
listItems = $('.tabela > li'),
// cache amount ref
amount = $('#amount'),
// collection of selected checkbox elements
selectedItems = [],
// slider config
slideOptions =
min: 500,
max: 100000,
step: 500,
values: [10000],
slide: function(event, ui)
amount.val(ui.values[0] + " USD");
,
change: function(event, ui)
updateList();
;
// render our slider
var slider = $("#price").slider(slideOptions);
amount.val($("#price").slider("values", 0) + " USD");
checkboxes.on('change', function()
var id = this.id;
if(this.checked)
// push the element vs the value
selectedItems.push(this.value);
else
// remove items on uncheck
selectedItems.splice(selectedItems.indexOf(this.value), 1);
updateList();
);
var updateList = function()
// create map of values for joining
var selectedItemsValues = selectedItems.sort().join(' '),
// min value
minPrice = slider.slider('values', 0);
// filter list items
listItems.hide().filter(function()
// get data attributes
var data = this.dataset;
// restrict list to price band and selections
return Number(data.price) > minPrice && (selectedItems.length ? data.category.includes(selectedItemsValues) : true);
)
.show();
// count visible li only
var total = $('.tabela li:visible').length;
if(total === 0)
results.html('We did not find any matches.');
else
results.html('We found ' + total + (total === 1 ? ' match' : ' matches' ) + '!');
);
.ui-slider
position: relative;
text-align: left;
.ui-slider .ui-slider-handle
position: absolute;
z-index: 2;
width: 1.2em;
height: 1.2em;
cursor: default;
.ui-slider .ui-slider-range
position: absolute;
z-index: 1;
font-size: .7em;
display: block;
border: 0;
background-position: 0 0;
.ui-slider-horizontal
height: .8em;
.ui-slider-horizontal .ui-slider-handle
top: -0.5em;
margin-left: -.6em;
.ui-slider-horizontal .ui-slider-range
top: 0;
height: 100%;
.ui-slider-horizontal .ui-slider-range-min
left: 0;
.ui-slider-horizontal .ui-slider-range-max
right: 0;
.ui-slider-vertical
width: .8em;
height: 100px;
.ui-slider-vertical .ui-slider-handle
left: -.3em;
margin-left: 0;
margin-bottom: -.6em;
.ui-slider-vertical .ui-slider-range
left: 0;
width: 100%;
.ui-slider-vertical .ui-slider-range-min
bottom: 0;
.ui-slider-vertical .ui-slider-range-max
top: 0;
.ui-widget-content
border: 1px solid #aaaaaa;
background: white 50% 50% repeat-x;
color: #222222;
.ui-widget
font-family: Verdana,Arial,sans-serif;
font-size: 1.1em;
.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default
width: 30px;
height: 30px;
border: 3px solid #2F3D44;
border-radius: 20px;
background: white 50% 50% repeat-x;
font-weight: normal;
color: #555555;
.slider1Hide
display: none;
<script src="https://code.jquery.com/jquery-1.7.2.min.js"></script>
<script src="https://code.jquery.com/ui/1.8.21/jquery-ui.min.js"></script>
<input type="text" id="amount" readonly>
<div class="slider" id="price"></div>
<br><br>
<div class="tabela-wrap">
<label for="1"><input type="checkbox" name="fl-1" value="1" id="1" /> 1</label>
<label for="2"><input type="checkbox" name="fl-2" value="2" id="2" /> 2</label>
<label for="3"><input type="checkbox" name="fl-3" value="3" id="3" /> 3</label>
<label for="4"><input type="checkbox" name="fl-4" value="4" id="4" /> 4</label>
<label for="5"><input type="checkbox" name="fl-5" value="5" id="5" /> 5</label>
<label for="6"><input type="checkbox" name="fl-6" value="6" id="6" /> 6</label>
<label for="7"><input type="checkbox" name="fl-7" value="7" id="7" /> 7</label>
<label for="8"><input type="checkbox" name="fl-8" value="8" id="8" /> 8</label>
</div>
<br><br>
<ul class="tabela lokata" id="products">
<li class="tabelki" data-price="10000" data-category="1 2 3 4 ">10 000 USD contains 1 2 3 4</li>
<li class="tabelki" data-price="12000" data-category="2 3">12 000 USD contains 2 3</li>
<li class="tabelki" data-price="13000" data-category="4 5">13 000 USD contains 4 5</li>
<li class="tabelki" data-price="14000" data-category="5 6 ">14 000 USD contains 5 6</li>
<li class="tabelki" data-price="12000" data-category="5">12 000 USD contains 5</li>
<li class="tabelki" data-price="14000" data-category="1 2">14 000 USD contains 1 2</li>
<li class="tabelki" data-price="16000" data-category="1 2 3">16 000 USD contains 1 2 3</li>
<li class="tabelki" data-price="20000" data-category="7 8">20 000 USD contains 7 8</li>
</ul>
<div id="results"></div>
JSFiddle
【讨论】:
它工作得几乎完美。我发现了一个假条件。当我将滑块设置为最低 500 美元并按下 1、2、3、4 复选框然后取消按下 1 时,突然我可以看到没有 4 的元素,这是我不应该看到的。我应该看到那些包含 2,3,4。你觉得那是什么? 更新:我在 splice 调用中有错字 效果很好。我印象深刻。非常感谢。 我试图在该示例中添加额外的范围滑块,但我失败了。你能看看这个案例吗? ***.com/questions/51916081/adding-range-slider【参考方案2】:问题是您正在添加和删除一个类slider1Hide
以显示/隐藏超出滑块范围的对象,但对复选框使用内联样式display: list-item
/display: none
。内联 css 样式始终优先于类中定义的样式,因此即使您的某个项目具有 slider1Hide
,如果它具有 display: list-item
,它仍会显示。你可以用浏览器的检查器观察这一点——你会看到一条穿过slider1Hide
的display
属性的线:
无论如何,为了解决您的问题,我已经更新了您的 javascript。 filterPrice()
和filterCheckboxes()
这两个函数接收产品列表并过滤掉那些应该保持隐藏的产品。那么show()
的代码就是剩下的产品了。
!function(a)function f(a,b)if(!(a.originalEvent.touches.length>1))a.preventDefault();var c=a.originalEvent.changedTouches[0],d=document.createEvent("MouseEvents");d.initMouseEvent(b,!0,!0,window,1,c.screenX,c.screenY,c.clientX,c.clientY,!1,!1,!1,!1,0,null),a.target.dispatchEvent(d)if(a.support.touch="ontouchend"in document,a.support.touch)var e,b=a.ui.mouse.prototype,c=b._mouseInit,d=b._mouseDestroy;b._touchStart=function(a)var b=this;!e&&b._mouseCapture(a.originalEvent.changedTouches[0])&&(e=!0,b._touchMoved=!1,f(a,"mouseover"),f(a,"mousemove"),f(a,"mousedown")),b._touchMove=function(a)e&&(this._touchMoved=!0,f(a,"mousemove")),b._touchEnd=function(a)e&&(f(a,"mouseup"),f(a,"mouseout"),this._touchMoved||f(a,"click"),e=!1),b._mouseInit=function()var b=this;b.element.bind(touchstart:a.proxy(b,"_touchStart"),touchmove:a.proxy(b,"_touchMove"),touchend:a.proxy(b,"_touchEnd")),c.call(b),b._mouseDestroy=function()var b=this;b.element.unbind(touchstart:a.proxy(b,"_touchStart"),touchmove:a.proxy(b,"_touchMove"),touchend:a.proxy(b,"_touchEnd")),d.call(b)(jQuery);
function filterPrice(products)
let minP = $("#price").slider("values", 0);
let maxP = $("#price").slider("values", 1);
return products.filter(function()
let value = parseInt($(this).data("price"), 10);
return !(value > maxP || value < minP);
);
function filterCheckboxes(products)
checkboxes = $("input:checked").filter(function()
return $.inArray($(this).attr("name"), ['fl-1', 'fl-2', 'fl-3', 'fl-4', 'fl-5', 'fl-6', 'fl-7', 'fl-8']) != -1;
).map(function()
return this.value;
);
// If no checkboxes are checked, don't filter with them
if (checkboxes.length == 0)
return products;
return products.filter(function()
categories = $(this).data("category").toString().split(" ");
let val = true;
checkboxes.each(function()
if (!categories.includes(this[0]))
val = false;
return;
);
return val;
);
function filterProducts()
// Reset filters
products = $("#products li");
products.hide();
products = filterPrice(products);
products = filterCheckboxes(products);
products.show();
let numItems = products.length;
if (numItems > 0)
label = "We found " + numItems + " results";
else
label = "No results found";
$("#found").text(label);
$(function()
let options =
min: 500,
max: 100000,
step: 500,
values: [10000],
slide: function(event, ui)
$("#amount").val(ui.values[0] + " USD");
,
change: function(event, ui)
filterProducts();
;
$("input").filter(function()
return $.inArray($(this).attr("name"), ['fl-1', 'fl-2', 'fl-3', 'fl-4', 'fl-5', 'fl-6', 'fl-7', 'fl-8']) != -1;
).change(filterProducts);
$("#price").slider(options);
$("#amount").val($("#price").slider("values", 0) + " USD");
);
http://jsfiddle.net/m1z930r5/84/
【讨论】:
以上是关于如何将滑块与其他复选框过滤器放在一起的主要内容,如果未能解决你的问题,请参考以下文章