如何将 Slider 与其他复选框过滤器放在一起

How to put Slider together with additional checkbox filter

我在协同工作时遇到问题 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;
}

JavaScript:

! 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;
}

有人能破案吗?

试试这个:

我对您的代码进行了大量重构,以使其更容易 read/understand 并保持干燥。我能够将行数从 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

问题是您在滑块范围外向 show/hide 添加和删除 class slider1Hide 对象,但使用的是内联样式 display: list-item/ display: none 用于复选框。内联 css 样式始终优先于 class 中定义的样式,因此即使您的其中一项具有 slider1Hide,如果它具有 display: list-item,它仍会显示。您可以使用浏览器的检查器观察这一点——您会看到一条通过 slider1Hidedisplay 属性的线:

无论如何,为了解决您的问题,我已经更新了您的 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/