问题
I have built a Isotope grid layout to display projects, which also uses the Isotope filtering to sort through the projects quicker.
The filtering works fine until you try to put the dropdowns back to their default position "All Services" & "All Sectors". Then all the projects are hidden, when they should all be displayed.
http://www.ellyon.co.uk/wp/projects/
EDIT: Is it possibly a Jquery conflict? I've added my functions.php as im not 100% sure ive added scripts correctly.
functions.php
function add_isotope() {
wp_register_script( 'isotope-init', get_template_directory_uri().'/js/isotope.js', array('jquery', 'isotope'), true );
wp_register_style( 'isotope-css', get_stylesheet_directory_uri() . '/styles/project.css' );
wp_enqueue_script('isotope-init');
wp_enqueue_style('isotope-css');
}
add_action( 'wp_enqueue_scripts', 'add_isotope' );
function modify_jquery() {
if ( !is_admin() ) {
wp_deregister_script( 'jquery' );
wp_register_script( 'jquery', 'https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js', false, '3.2.1' );
wp_enqueue_script( 'jquery' );
}
}
add_action( 'init', 'modify_jquery' );
Isotope.js
// Grid
var $grid = $('.grid').isotope({
itemSelector: '.grid-item',
layoutMode: 'packery',
columnWidth: '.grid-sizer',
packery: {
gutter: '.gutter-sizer'
}
});
// state variable
var $expandedItem;
// expand when clicked
$grid.on( 'click', '.grid-item', function( event ) {
var isExpanded = $expandedItem && event.currentTarget == $expandedItem[0];
if ( isExpanded ) {
// exit if already expanded
return;
}
// un-expand previous
if ( $expandedItem ) {
$expandedItem.removeClass('gigante');
}
// set new & expand
$expandedItem = $( event.currentTarget ).addClass('gigante');
$grid.isotope('layout');
});
$grid.on( 'click', '.close-button button', function( event ) {
$expandedItem.removeClass('gigante');
// reset variable
$expandedItem = null;
$grid.isotope('layout');
event.stopPropagation();
});
// Select Filters
$(function() {
var $container = $('.grid'),
$select = $('div#filterGroup select');
filters = {};
$container.isotope({
itemSelector: '.grid-item'
});
$select.change(function() {
var $this = $(this);
var $optionSet = $this;
var group = $optionSet.attr('data-filter-group');
filters[group] = $this.find('option:selected').attr('data-filter-value');
var isoFilters = [];
for (var prop in filters) {
isoFilters.push(filters[prop])
}
var selector = isoFilters.join('');
$container.isotope({
filter: selector
});
return false;
});
$grid.imagesLoaded().progress( function() {
$grid.isotope('layout');
});
});
回答1:
Asterisk, *
, is a special case and need to be handled differently from other filter values such that:
- if one or more non-asterisk value is selected, then all asterisks should be ignored
- if no non-asterisk value is selected, then default to a single asterisk (show all).
There must be a number of ways to implement those rules. Here's one :
// Select Filters
$(function() {
var $grid = $('.grid');
var $selects = $('div#filterGroup select').change(function() {
var selector = $selects.get().map(function(el) { // map the select elements ...
return $(el).data('filter-value'); // ... to an array of filter-values
}).filter(function(val) {
return val !== '*' // filter out all '*' values
}).join('') || '*'; // if joined array is empty-string, then default to a single '*'
$grid.isotope({
'filter': selector
});
return false;
});
...
});
Note that the original code's filters
object only adds unnecessary complexity. The DOM is very good at representing its own state, so instead of maintaining a persistent mapping in javascript, it's simpler to map both select elements directly to Array every time there is a change to either one of them.
The code would simplify slightly if the HTML was constructed as follows :
<select class="filter option-set" data-filter-group="services">
<option value="">All Services</option>
<option value='.cladding'>Cladding</option>
...
</select>
<select class="filter option-set" data-filter-group="sectors">
<option value="">All Sectors</option>
<option value='.commerical'>Commerical</option>
...
</select>
Then, the need to .filter()
out asterisks would disappear, leaving :
$(function() {
var $grid = $('.grid');
var $selects = $('div#filterGroup select').change(function() {
var selector = $selects.get().map(function(el) { // map the select elements ...
return $(el).val(); // ... to an array of values
}).join('') || '*'; // if joined array is empty-string, then default to a single '*'
$grid.isotope({
'filter': selector
});
return false;
});
...
});
来源:https://stackoverflow.com/questions/50451048/isotope-filtering-issues-when-reset-to-start-position