同位素 - 组合按钮和 UI 滑块不起作用
Isotope - combination buttons and UI slider not working
我正在尝试让 Isotope 插件使用组合按钮和 UI 滑块进行过滤,但不确定如何去做。
谁能帮我实现这个。
这是 link 我的问题 code pen test case
<h1>Isotope - combination filters</h1>
<div class="filters">
<div class="ui-group">
<h3>Color</h3>
<div class="button-group js-radio-button-group" data-filter-group="color">
<button class="button is-checked" data-filter="">any</button>
<button class="button" data-filter=".red">red</button>
<button class="button" data-filter=".blue">blue</button>
<button class="button" data-filter=".yellow">yellow</button>
</div>
</div>
<div class="ui-group">
<h3>Size</h3>
<div class="button-group js-radio-button-group" data-filter-group="size">
<button class="button is-checked" data-filter="">any</button>
<button class="button" data-filter=".small">small</button>
<button class="button" data-filter=".wide">wide</button>
<button class="button" data-filter=".big">big</button>
<button class="button" data-filter=".tall">tall</button>
</div>
</div>
<div class="ui-group">
<h3>Shape</h3>
<div class="button-group js-radio-button-group" data-filter-group="shape">
<button class="button is-checked" data-filter="">any</button>
<button class="button" data-filter=".round">round</button>
<button class="button" data-filter=".square">square</button>
</div>
</div>
<div class="sliders" data-filter-group="features">
<div class="noUi-target noUi-ltr noUi-horizontal noUi-background" id="slider-range"></div>
<span class="val" id="slider-range-value"></span>
</div>
</div>
<div class="grid">
<div class="color-shape small round red">180.00</div>
<div class="color-shape small round blue">195.00</div>
<div class="color-shape small round yellow">202.00</div>
<div class="color-shape small square red">235.00</div>
<div class="color-shape small square blue">240.00</div>
<div class="color-shape small square yellow">250.00</div>
<div class="color-shape wide round red">255.00</div>
<div class="color-shape wide round blue">275.00</div>
<div class="color-shape wide round yellow">285.00</div>
<div class="color-shape wide square red">290.00</div>
<div class="color-shape wide square blue">295.00</div>
<div class="color-shape wide square yellow">300.00</div>
<div class="color-shape big round red">300.00</div>
<div class="color-shape big round blue">300.00</div>
<div class="color-shape big round yellow">300.00</div>
<div class="color-shape big square red">300.00</div>
<div class="color-shape big square blue">180.00</div>
<div class="color-shape big square yellow">180.00</div>
<div class="color-shape tall round red">180.00</div>
<div class="color-shape tall round blue">180.00</div>
<div class="color-shape tall round yellow">255.00</div>
<div class="color-shape tall square red">255.00</div>
<div class="color-shape tall square blue">255.00</div>
<div class="color-shape tall square yellow">255.00</div>
</div>
$( function() {
// filter functions
var filterFns = {
greaterThan50: function() {
var number = $(this).find('.number').text();
return parseInt( number, 10 ) > 50.00;
},
even: function() {
var number = $(this).find('.number').text();
return parseInt( number, 10 ) % 2 === 0;
}
};
// init Isotope
var $container = $('.isotope').isotope({
itemSelector: '.color-shape',
filter: function() {
var isMatched = true;
var $this = $(this);
for ( var prop in filters ) {
var filter = filters[ prop ];
// use function if it matches
filter = filterFns[ filter ] || filter;
// test each filter
if ( filter ) {
isMatched = isMatched && $(this).is( filter );
}
// break if not matched
if ( !isMatched ) {
break;
}
}
return isMatched;
}
});
// store filter for each group
var filters = {};
$('#filters').on( 'click', '.button', function() {
var $this = $(this);
// get group key
var $buttonGroup = $this.parents('.button-group');
var filterGroup = $buttonGroup.attr('data-filter-group');
// set filter for group
filters[ filterGroup ] = $this.attr('data-filter');
// arrange, and use filter fn
$container.isotope('arrange');
});
// change is-checked class on buttons
$('.button-group').each( function( i, buttonGroup ) {
var $buttonGroup = $( buttonGroup );
$buttonGroup.on( 'click', 'button', function() {
$buttonGroup.find('.is-checked').removeClass('is-checked');
$( this ).addClass('is-checked');
});
});
});
* {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
body {
font-family: sans-serif;
}
/* ---- button ---- */
.button {
display: inline-block;
padding: 0.5em 1.0em;
background: #EEE;
border: none;
border-radius: 7px;
background-image: linear-gradient( to bottom, hsla(0, 0%, 0%, 0), hsla(0, 0%, 0%, 0.2) );
color: #222;
font-family: sans-serif;
font-size: 16px;
text-shadow: 0 1px white;
cursor: pointer;
}
.button:hover {
background-color: #8CF;
text-shadow: 0 1px hsla(0, 0%, 100%, 0.5);
color: #222;
}
.button:active,
.button.is-checked {
background-color: #28F;
}
.button.is-checked {
color: white;
text-shadow: 0 -1px hsla(0, 0%, 0%, 0.8);
}
.button:active {
box-shadow: inset 0 1px 10px hsla(0, 0%, 0%, 0.8);
}
/* ---- button-group ---- */
.button-group:after {
content: '';
display: block;
clear: both;
}
.button-group .button {
float: left;
border-radius: 0;
margin-left: 0;
margin-right: 1px;
}
.button-group .button:first-child { border-radius: 0.5em 0 0 0.5em; }
.button-group .button:last-child { border-radius: 0 0.5em 0.5em 0; }
/* ---- isotope ---- */
.grid {
background: #EEE;
max-width: 1200px;
}
/* clear fix */
.grid:after {
content: '';
display: block;
clear: both;
}
/* ui group */
.ui-group {
display: inline-block;
}
.ui-group h3 {
display: inline-block;
vertical-align: top;
line-height: 32px;
margin-right: 0.2em;
font-size: 16px;
}
.ui-group .button-group {
display: inline-block;
margin-right: 20px;
}
/* color-shape */
.color-shape {
width: 70px;
height: 70px;
margin: 5px;
float: left;
}
.color-shape.round {
border-radius: 35px;
}
.color-shape.big.round {
border-radius: 75px;
}
.color-shape.red { background: red; }
.color-shape.blue { background: blue; }
.color-shape.yellow { background: yellow; }
.color-shape.wide, .color-shape.big { width: 150px; }
.color-shape.tall, .color-shape.big { height: 150px; }
/* Functional styling for range slider;
* These styles are required for noUiSlider to function.
* You don't need to change these rules to apply your design.
*/
.noUi-target,
.noUi-target * {
-webkit-touch-callout: none;
-webkit-user-select: none;
-ms-touch-action: none;
touch-action: none;
-ms-user-select: none;
-moz-user-select: none;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.noUi-target {
position: relative;
direction: ltr;
width: 62%;
margin-left: 20px;
}
.noUi-base {
width: 100%;
height: 100%;
position: relative;
z-index: 1; /* Fix 401 */
}
.noUi-origin {
position: absolute;
right: 0;
top: 0;
left: 0;
bottom: 0;
}
.noUi-handle {
position: relative;
z-index: 1;
}
.noUi-stacking .noUi-handle {
/* This class is applied to the lower origin when
its values is > 50%. */
z-index: 10;
}
.noUi-state-tap .noUi-origin {
-webkit-transition: left 0.3s, top 0.3s;
transition: left 0.3s, top 0.3s;
}
.noUi-state-drag * {
cursor: inherit !important;
}
/* Painting and performance;
* Browsers can paint handles in their own layer.
*/
.noUi-base {
-webkit-transform: translate3d(0,0,0);
transform: translate3d(0,0,0);
}
/* Slider size and handle placement;
*/
.noUi-horizontal {
height: 18px;
}
.noUi-horizontal .noUi-handle {
width: 35px;
height: 26px;
left: -17px;
top: -5px;
}
.noUi-vertical {
width: 18px;
}
.noUi-vertical .noUi-handle {
width: 35px;
height: 26px;
left: -6px;
top: -5px;
}
/* Styling;
*/
.noUi-background {
background: #EEE linear-gradient(to bottom, transparent, rgba(0, 0, 0, 0.2)) repeat scroll 0% 0%;
box-shadow: inset 0 1px 1px #f0f0f0;
}
.noUi-connect {
background: #3FB8AF;
box-shadow: inset 0 0 3px rgba(51,51,51,0.45);
-webkit-transition: background 450ms;
transition: background 450ms;
}
.noUi-origin {
border-radius: 2px;
}
.noUi-target {
border-radius: 8px;
border: 1px solid #D3D3D3;
box-shadow: inset 0 1px 1px #F0F0F0, 0 3px 6px -5px #BBB;
}
.noUi-target.noUi-connect {
box-shadow: inset 0 0 3px rgba(51,51,51,0.45), 0 3px 6px -5px #BBB;
}
/* Handles and cursors;
*/
.noUi-draggable {
cursor: w-resize;
}
.noUi-vertical .noUi-draggable {
cursor: n-resize;
}
.noUi-handle {
border-radius: 8px;
background: #7D64B1;
cursor: grab;
}
.noUi-active {
box-shadow: 0px 1px 10px rgba(0, 0, 0, 0.8) inset;
cursor: grabbing;
}
/* Handle stripes;
*/
.noUi-handle:before,
.noUi-handle:after {
content: "";
display: block;
position: absolute;
height: 14px;
width: 1px;
background: #E8E7E6;
left: 14px;
top: 6px;
}
.noUi-handle:after {
left: 19px;
}
.noUi-vertical .noUi-handle:before,
.noUi-vertical .noUi-handle:after {
width: 14px;
height: 1px;
left: 6px;
top: 14px;
}
.noUi-vertical .noUi-handle:after {
top: 17px;
}
/* Disabled state;
*/
[disabled].noUi-connect,
[disabled] .noUi-connect {
background: #B8B8B8;
}
[disabled].noUi-origin,
[disabled] .noUi-handle {
cursor: not-allowed;
}
.val{
margin: 9px 0px 0px;
width: 8%;
display: block;
}
.color-shape{
text-indent:-9999px;
}
如果有人能提供帮助,我们将不胜感激。
让我们试一试。 See my demo on CodePen
诀窍是使用 filter function for Isotope。我们可以更改过滤器逻辑中使用的值,而不是更改过滤器。对于这个演示,我们有两个值:buttonFilter
和 sliderValue
。我已经设置了过滤功能来检查项目是否匹配 buttonFilter
并且具有大于或等于 sliderValue
.
的文本值
// external js: isotope.pkgd.js
$(document).ready( function() {
var sliderValue = 180;
// create the slider;
var rangeSlider = document.getElementById('slider-range');
noUiSlider.create(rangeSlider, {
start: [ 180 ],
range: {
'min': [ 180 ],
'max': [ 300 ]
}
});
// create the slider range value;
var rangeSliderValueElement = document.getElementById('slider-range-value');
rangeSlider.noUiSlider.on('update', function( values, handle ) {
rangeSliderValueElement.innerHTML = values[handle] + " cm";
});
// store filter for each group
var buttonFilters = {};
var buttonFilter = '*';
// init Isotope
var $grid = $('.grid').isotope({
itemSelector: '.color-shape',
// use filter function
filter: function() {
var $this = $(this);
var isMinSize = parseFloat( $this.text() ) >= sliderValue;
return $this.is( buttonFilter ) && isMinSize;
}
});
$('.filters').on( 'click', '.button', function() {
var $this = $(this);
// get group key
var $buttonGroup = $this.parents('.button-group');
var filterGroup = $buttonGroup.attr('data-filter-group');
// set filter for group
buttonFilters[ filterGroup ] = $this.attr('data-filter');
// combine filters
buttonFilter = concatValues( buttonFilters ) || '*';
console.log( buttonFilter )
// set filter for Isotope
$grid.isotope();
});
// filter isotope on slider set
rangeSlider.noUiSlider.on( 'set', function( textValues, handle, values ) {
sliderValue = values[ handle ];
$grid.isotope();
});
// change is-checked class on buttons
$('.button-group').each( function( i, buttonGroup ) {
var $buttonGroup = $( buttonGroup );
$buttonGroup.on( 'click', 'button', function() {
$buttonGroup.find('.is-checked').removeClass('is-checked');
$( this ).addClass('is-checked');
});
});
});
// flatten object by concatting values
function concatValues( obj ) {
var value = '';
for ( var prop in obj ) {
value += obj[ prop ];
}
return value;
}
我正在尝试让 Isotope 插件使用组合按钮和 UI 滑块进行过滤,但不确定如何去做。
谁能帮我实现这个。
这是 link 我的问题 code pen test case
<h1>Isotope - combination filters</h1>
<div class="filters">
<div class="ui-group">
<h3>Color</h3>
<div class="button-group js-radio-button-group" data-filter-group="color">
<button class="button is-checked" data-filter="">any</button>
<button class="button" data-filter=".red">red</button>
<button class="button" data-filter=".blue">blue</button>
<button class="button" data-filter=".yellow">yellow</button>
</div>
</div>
<div class="ui-group">
<h3>Size</h3>
<div class="button-group js-radio-button-group" data-filter-group="size">
<button class="button is-checked" data-filter="">any</button>
<button class="button" data-filter=".small">small</button>
<button class="button" data-filter=".wide">wide</button>
<button class="button" data-filter=".big">big</button>
<button class="button" data-filter=".tall">tall</button>
</div>
</div>
<div class="ui-group">
<h3>Shape</h3>
<div class="button-group js-radio-button-group" data-filter-group="shape">
<button class="button is-checked" data-filter="">any</button>
<button class="button" data-filter=".round">round</button>
<button class="button" data-filter=".square">square</button>
</div>
</div>
<div class="sliders" data-filter-group="features">
<div class="noUi-target noUi-ltr noUi-horizontal noUi-background" id="slider-range"></div>
<span class="val" id="slider-range-value"></span>
</div>
</div>
<div class="grid">
<div class="color-shape small round red">180.00</div>
<div class="color-shape small round blue">195.00</div>
<div class="color-shape small round yellow">202.00</div>
<div class="color-shape small square red">235.00</div>
<div class="color-shape small square blue">240.00</div>
<div class="color-shape small square yellow">250.00</div>
<div class="color-shape wide round red">255.00</div>
<div class="color-shape wide round blue">275.00</div>
<div class="color-shape wide round yellow">285.00</div>
<div class="color-shape wide square red">290.00</div>
<div class="color-shape wide square blue">295.00</div>
<div class="color-shape wide square yellow">300.00</div>
<div class="color-shape big round red">300.00</div>
<div class="color-shape big round blue">300.00</div>
<div class="color-shape big round yellow">300.00</div>
<div class="color-shape big square red">300.00</div>
<div class="color-shape big square blue">180.00</div>
<div class="color-shape big square yellow">180.00</div>
<div class="color-shape tall round red">180.00</div>
<div class="color-shape tall round blue">180.00</div>
<div class="color-shape tall round yellow">255.00</div>
<div class="color-shape tall square red">255.00</div>
<div class="color-shape tall square blue">255.00</div>
<div class="color-shape tall square yellow">255.00</div>
</div>
$( function() {
// filter functions
var filterFns = {
greaterThan50: function() {
var number = $(this).find('.number').text();
return parseInt( number, 10 ) > 50.00;
},
even: function() {
var number = $(this).find('.number').text();
return parseInt( number, 10 ) % 2 === 0;
}
};
// init Isotope
var $container = $('.isotope').isotope({
itemSelector: '.color-shape',
filter: function() {
var isMatched = true;
var $this = $(this);
for ( var prop in filters ) {
var filter = filters[ prop ];
// use function if it matches
filter = filterFns[ filter ] || filter;
// test each filter
if ( filter ) {
isMatched = isMatched && $(this).is( filter );
}
// break if not matched
if ( !isMatched ) {
break;
}
}
return isMatched;
}
});
// store filter for each group
var filters = {};
$('#filters').on( 'click', '.button', function() {
var $this = $(this);
// get group key
var $buttonGroup = $this.parents('.button-group');
var filterGroup = $buttonGroup.attr('data-filter-group');
// set filter for group
filters[ filterGroup ] = $this.attr('data-filter');
// arrange, and use filter fn
$container.isotope('arrange');
});
// change is-checked class on buttons
$('.button-group').each( function( i, buttonGroup ) {
var $buttonGroup = $( buttonGroup );
$buttonGroup.on( 'click', 'button', function() {
$buttonGroup.find('.is-checked').removeClass('is-checked');
$( this ).addClass('is-checked');
});
});
});
* {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
body {
font-family: sans-serif;
}
/* ---- button ---- */
.button {
display: inline-block;
padding: 0.5em 1.0em;
background: #EEE;
border: none;
border-radius: 7px;
background-image: linear-gradient( to bottom, hsla(0, 0%, 0%, 0), hsla(0, 0%, 0%, 0.2) );
color: #222;
font-family: sans-serif;
font-size: 16px;
text-shadow: 0 1px white;
cursor: pointer;
}
.button:hover {
background-color: #8CF;
text-shadow: 0 1px hsla(0, 0%, 100%, 0.5);
color: #222;
}
.button:active,
.button.is-checked {
background-color: #28F;
}
.button.is-checked {
color: white;
text-shadow: 0 -1px hsla(0, 0%, 0%, 0.8);
}
.button:active {
box-shadow: inset 0 1px 10px hsla(0, 0%, 0%, 0.8);
}
/* ---- button-group ---- */
.button-group:after {
content: '';
display: block;
clear: both;
}
.button-group .button {
float: left;
border-radius: 0;
margin-left: 0;
margin-right: 1px;
}
.button-group .button:first-child { border-radius: 0.5em 0 0 0.5em; }
.button-group .button:last-child { border-radius: 0 0.5em 0.5em 0; }
/* ---- isotope ---- */
.grid {
background: #EEE;
max-width: 1200px;
}
/* clear fix */
.grid:after {
content: '';
display: block;
clear: both;
}
/* ui group */
.ui-group {
display: inline-block;
}
.ui-group h3 {
display: inline-block;
vertical-align: top;
line-height: 32px;
margin-right: 0.2em;
font-size: 16px;
}
.ui-group .button-group {
display: inline-block;
margin-right: 20px;
}
/* color-shape */
.color-shape {
width: 70px;
height: 70px;
margin: 5px;
float: left;
}
.color-shape.round {
border-radius: 35px;
}
.color-shape.big.round {
border-radius: 75px;
}
.color-shape.red { background: red; }
.color-shape.blue { background: blue; }
.color-shape.yellow { background: yellow; }
.color-shape.wide, .color-shape.big { width: 150px; }
.color-shape.tall, .color-shape.big { height: 150px; }
/* Functional styling for range slider;
* These styles are required for noUiSlider to function.
* You don't need to change these rules to apply your design.
*/
.noUi-target,
.noUi-target * {
-webkit-touch-callout: none;
-webkit-user-select: none;
-ms-touch-action: none;
touch-action: none;
-ms-user-select: none;
-moz-user-select: none;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.noUi-target {
position: relative;
direction: ltr;
width: 62%;
margin-left: 20px;
}
.noUi-base {
width: 100%;
height: 100%;
position: relative;
z-index: 1; /* Fix 401 */
}
.noUi-origin {
position: absolute;
right: 0;
top: 0;
left: 0;
bottom: 0;
}
.noUi-handle {
position: relative;
z-index: 1;
}
.noUi-stacking .noUi-handle {
/* This class is applied to the lower origin when
its values is > 50%. */
z-index: 10;
}
.noUi-state-tap .noUi-origin {
-webkit-transition: left 0.3s, top 0.3s;
transition: left 0.3s, top 0.3s;
}
.noUi-state-drag * {
cursor: inherit !important;
}
/* Painting and performance;
* Browsers can paint handles in their own layer.
*/
.noUi-base {
-webkit-transform: translate3d(0,0,0);
transform: translate3d(0,0,0);
}
/* Slider size and handle placement;
*/
.noUi-horizontal {
height: 18px;
}
.noUi-horizontal .noUi-handle {
width: 35px;
height: 26px;
left: -17px;
top: -5px;
}
.noUi-vertical {
width: 18px;
}
.noUi-vertical .noUi-handle {
width: 35px;
height: 26px;
left: -6px;
top: -5px;
}
/* Styling;
*/
.noUi-background {
background: #EEE linear-gradient(to bottom, transparent, rgba(0, 0, 0, 0.2)) repeat scroll 0% 0%;
box-shadow: inset 0 1px 1px #f0f0f0;
}
.noUi-connect {
background: #3FB8AF;
box-shadow: inset 0 0 3px rgba(51,51,51,0.45);
-webkit-transition: background 450ms;
transition: background 450ms;
}
.noUi-origin {
border-radius: 2px;
}
.noUi-target {
border-radius: 8px;
border: 1px solid #D3D3D3;
box-shadow: inset 0 1px 1px #F0F0F0, 0 3px 6px -5px #BBB;
}
.noUi-target.noUi-connect {
box-shadow: inset 0 0 3px rgba(51,51,51,0.45), 0 3px 6px -5px #BBB;
}
/* Handles and cursors;
*/
.noUi-draggable {
cursor: w-resize;
}
.noUi-vertical .noUi-draggable {
cursor: n-resize;
}
.noUi-handle {
border-radius: 8px;
background: #7D64B1;
cursor: grab;
}
.noUi-active {
box-shadow: 0px 1px 10px rgba(0, 0, 0, 0.8) inset;
cursor: grabbing;
}
/* Handle stripes;
*/
.noUi-handle:before,
.noUi-handle:after {
content: "";
display: block;
position: absolute;
height: 14px;
width: 1px;
background: #E8E7E6;
left: 14px;
top: 6px;
}
.noUi-handle:after {
left: 19px;
}
.noUi-vertical .noUi-handle:before,
.noUi-vertical .noUi-handle:after {
width: 14px;
height: 1px;
left: 6px;
top: 14px;
}
.noUi-vertical .noUi-handle:after {
top: 17px;
}
/* Disabled state;
*/
[disabled].noUi-connect,
[disabled] .noUi-connect {
background: #B8B8B8;
}
[disabled].noUi-origin,
[disabled] .noUi-handle {
cursor: not-allowed;
}
.val{
margin: 9px 0px 0px;
width: 8%;
display: block;
}
.color-shape{
text-indent:-9999px;
}
如果有人能提供帮助,我们将不胜感激。
让我们试一试。 See my demo on CodePen
诀窍是使用 filter function for Isotope。我们可以更改过滤器逻辑中使用的值,而不是更改过滤器。对于这个演示,我们有两个值:buttonFilter
和 sliderValue
。我已经设置了过滤功能来检查项目是否匹配 buttonFilter
并且具有大于或等于 sliderValue
.
// external js: isotope.pkgd.js
$(document).ready( function() {
var sliderValue = 180;
// create the slider;
var rangeSlider = document.getElementById('slider-range');
noUiSlider.create(rangeSlider, {
start: [ 180 ],
range: {
'min': [ 180 ],
'max': [ 300 ]
}
});
// create the slider range value;
var rangeSliderValueElement = document.getElementById('slider-range-value');
rangeSlider.noUiSlider.on('update', function( values, handle ) {
rangeSliderValueElement.innerHTML = values[handle] + " cm";
});
// store filter for each group
var buttonFilters = {};
var buttonFilter = '*';
// init Isotope
var $grid = $('.grid').isotope({
itemSelector: '.color-shape',
// use filter function
filter: function() {
var $this = $(this);
var isMinSize = parseFloat( $this.text() ) >= sliderValue;
return $this.is( buttonFilter ) && isMinSize;
}
});
$('.filters').on( 'click', '.button', function() {
var $this = $(this);
// get group key
var $buttonGroup = $this.parents('.button-group');
var filterGroup = $buttonGroup.attr('data-filter-group');
// set filter for group
buttonFilters[ filterGroup ] = $this.attr('data-filter');
// combine filters
buttonFilter = concatValues( buttonFilters ) || '*';
console.log( buttonFilter )
// set filter for Isotope
$grid.isotope();
});
// filter isotope on slider set
rangeSlider.noUiSlider.on( 'set', function( textValues, handle, values ) {
sliderValue = values[ handle ];
$grid.isotope();
});
// change is-checked class on buttons
$('.button-group').each( function( i, buttonGroup ) {
var $buttonGroup = $( buttonGroup );
$buttonGroup.on( 'click', 'button', function() {
$buttonGroup.find('.is-checked').removeClass('is-checked');
$( this ).addClass('is-checked');
});
});
});
// flatten object by concatting values
function concatValues( obj ) {
var value = '';
for ( var prop in obj ) {
value += obj[ prop ];
}
return value;
}