我正在使用 Ajax 过滤插件 构建一个 WP 在线商店,它按类别等过滤产品。当我单击一个类别按钮时,它请求 URL 两次,就好像该函数被执行了两次一样。我用萤火虫控制台检查了行为 - 它两次请求 URL。任何帮助将不胜感激。
jQuery(document).ready(function($) {
// return false if wcapf_params variable is not found
if (typeof wcapf_params === 'undefined') {
return false;
}
// store widget ids those will be replaced with new data
var widgets = {};
$('.wcapf-ajax-term-filter').each(function(index) {
var widget_id = $(this).attr('id');
widgets[index] = widget_id;
});
// scripts to run before updating shop loop
wcapfBeforeUpdate = function() {
var overlay_color;
if (wcapf_params.overlay_bg_color.length) {
overlay_color = wcapf_params.overlay_bg_color;
} else {
overlay_color = '#fff';
}
var markup = '<div class="wcapf-before-update" style="background-color: ' + overlay_color + '"></div>',
holder,
top_scroll_offset = 0;
if ($(wcapf_params.shop_loop_container.length)) {
holder = wcapf_params.shop_loop_container;
} else if ($(wcapf_params.not_found_container).length) {
holder = wcapf_params.not_found_container;
}
if (holder.length) {
// show loading image
$(markup).prependTo(holder);
// scroll to top
if (typeof wcapf_params.scroll_to_top !== 'undefined' && wcapf_params.scroll_to_top == true) {
var scroll_to_top_offset,
top_scroll_offset;
if (typeof wcapf_params.scroll_to_top_offset !== 'undefined' && wcapf_params.scroll_to_top_offset.length) {
scroll_to_top_offset = parseInt(wcapf_params.scroll_to_top_offset);
} else {
scroll_to_top_offset = 100;
}
top_scroll_offset = $(holder).offset().top - scroll_to_top_offset;
if (top_scroll_offset < 0) {
top_scroll_offset = 0;
}
$('html, body').animate({scrollTop: top_scroll_offset}, 'slow');
}
}
}
// scripts to run after updating shop loop
wcapfAfterUpdate = function() {}
// load filtered products
wcapfFilterProducts = function() {
// run before update function: show a loading image and scroll to top
wcapfBeforeUpdate();
$.get(window.location.href, function(data) {
var $data = jQuery(data),
shop_loop = $data.find(wcapf_params.shop_loop_container),
not_found = $data.find(wcapf_params.not_found_container);
// replace widgets data with new data
$.each(widgets, function(index, id) {
var single_widget = $data.find('#' + id),
single_widget_class = $(single_widget).attr('class');
// update class
$('#' + id).attr('class', single_widget_class);
// update widget
$('#' + id).html(single_widget.html());
});
// replace old shop loop with new one
if (wcapf_params.shop_loop_container == wcapf_params.not_found_container) {
$(wcapf_params.shop_loop_container).html(shop_loop.html());
} else {
if ($(wcapf_params.not_found_container).length) {
if (shop_loop.length) {
$(wcapf_params.not_found_container).html(shop_loop.html());
} else if (not_found.length) {
$(wcapf_params.not_found_container).html(not_found.html());
}
} else if ($(wcapf_params.shop_loop_container).length) {
if (shop_loop.length) {
$(wcapf_params.shop_loop_container).html(shop_loop.html());
} else if (not_found.length) {
$(wcapf_params.shop_loop_container).html(not_found.html());
}
}
}
// reinitialize ordering
wcapfInitOrder();
// reinitialize dropdown filter
wcapfDropDownFilter();
// run scripts after shop loop undated
if (typeof wcapf_params.custom_scripts !== 'undefined' && wcapf_params.custom_scripts.length > 0) {
eval(wcapf_params.custom_scripts);
}
});
}
// URL Parser
wcapfGetUrlVars = function(url) {
var vars = {}, hash;
if (typeof url == 'undefined') {
url = window.location.href;
} else {
url = url;
}
// THIS ONE DONT WORK - FROM THE ORIGINAL PLUGIN !!!!
// var hashes = url.slice(url.indexOf('?') + 1).split('&');
// for (var i = 0; i < hashes.length; i++) {
// hash = hashes[i].split('=');
// vars[hash[0]] = hash[1];
// }
// return vars;
// THIS PART WORKS - FROM https://stackoverflow.com/a/12727153
var vars = [], hash;
var hashes = url.slice(url.indexOf('?') + 1).split('&');
for(var i = 0; i < hashes.length; i++) {
hash = hashes[i].split('=');
vars.push(hash[0]);
vars[hash[0]] = hash[1];
}
return vars;
}
// if current page is greater than 1 then we should set it to 1
// every time we add new query to URL to prevent page not found error.
wcapfFixPagination = function() {
var url = window.location.href,
params = wcapfGetUrlVars(url);
if (current_page = parseInt(url.replace(/.+\/page\/([0-9]+)+/, "$1"))) {
if (current_page > 1) {
url = url.replace(/page\/([0-9]+)/, 'page/1');
}
}
else if(typeof params['paged'] != 'undefined') {
current_page = parseInt(params['paged']);
if (current_page > 1) {
url = url.replace('paged=' + current_page, 'paged=1');
}
}
return url;
}
// update query string for categories, meta etc..
wcapfUpdateQueryStringParameter = function(key, value, push_history, url) {
if (typeof push_history === 'undefined') {
push_history = true;
}
if (typeof url === 'undefined') {
url = wcapfFixPagination();
}
var re = new RegExp("([?&])" + key + "=.*?(&|$)", "i"),
separator = url.indexOf('?') !== -1 ? "&" : "?",
url_with_query;
if (url.match(re)) {
url_with_query = url.replace(re, '$1' + key + "=" + value + '$2');
}
else {
url_with_query = url + separator + key + "=" + value;
}
if (push_history === true) {
return history.pushState({}, '', url_with_query);
} else {
return url_with_query;
}
}
// remove parameter from url
wcapfRemoveQueryStringParameter = function(filter_key, url) {
if (typeof url === 'undefined') {
url = wcapfFixPagination();
}
var params = wcapfGetUrlVars(url),
count_params = Object.keys(params).length,
start_position = url.indexOf('?'),
param_position = url.indexOf(filter_key),
clean_url,
clean_query;
if (count_params > 1) {
if ((param_position - start_position) > 1) {
clean_url = url.replace('&' + filter_key + '=' + params[filter_key], '');
} else {
clean_url = url.replace(filter_key + '=' + params[filter_key] + '&', '');
}
var params = clean_url.split('?');
clean_query = '?' + params[1];
} else {
clean_query = url.replace('?' + filter_key + '=' + params[filter_key], '');
}
return clean_query;
}
// add filter if not exists else remove filter
wcapfSingleFilter = function(filter_key, filter_val) {
var params = wcapfGetUrlVars(),
query;
if (typeof params[filter_key] !== 'undefined' && params[filter_key] == filter_val) {
query = wcapfRemoveQueryStringParameter(filter_key);
} else {
query = wcapfUpdateQueryStringParameter(filter_key, filter_val, false);
}
// update url
history.pushState({}, '', query);
// filter products
wcapfFilterProducts();
}
// take the key and value and make query
wcapfMakeParameters = function(filter_key, filter_val, url) {
var params,
next_vals,
empty_val = false;
if (typeof url !== 'undefined') {
params = wcapfGetUrlVars(url);
} else {
params = wcapfGetUrlVars();
}
if (typeof params[filter_key] != 'undefined') {
var prev_vals = params[filter_key],
prev_vals_array = prev_vals.split(',');
if (prev_vals.length > 0) {
var found = jQuery.inArray(filter_val, prev_vals_array);
if (found >= 0) {
// Element was found, remove it.
prev_vals_array.splice(found, 1);
if (prev_vals_array.length == 0) {
empty_val = true;
}
} else {
// Element was not found, add it.
prev_vals_array.push(filter_val);
}
if (prev_vals_array.length > 1) {
next_vals = prev_vals_array.join(',');
} else {
next_vals = prev_vals_array;
}
} else {
next_vals = filter_val;
}
} else {
next_vals = filter_val;
}
// update url and query string
if (empty_val == false) {
wcapfUpdateQueryStringParameter(filter_key, next_vals);
} else {
var query = wcapfRemoveQueryStringParameter(filter_key);
history.pushState({}, '', query);
}
// filter products
wcapfFilterProducts();
}
// handle the filter request
$('.wcapf-ajax-term-filter').not('.wcapf-price-filter-widget').on('click', 'li a', function(event) {
event.preventDefault();
var element = $(this),
filter_key = element.attr('data-key'),
filter_val = element.attr('data-value'),
enable_multiple_filter = element.attr('data-multiple-filter');
if (enable_multiple_filter == true) {
wcapfMakeParameters(filter_key, filter_val);
} else {
wcapfSingleFilter(filter_key, filter_val);
}
});
// handle the filter request for price filter display type list
$('.wcapf-price-filter-widget.wcapf-ajax-term-filter').on('click', 'li a', function(event) {
event.preventDefault();
var element = $(this),
filter_key_min = element.attr('data-key-min'),
filter_val_min = element.attr('data-value-min'),
filter_key_max = element.attr('data-key-max'),
filter_val_max = element.attr('data-value-max'),
query;
if (element.parent().hasClass('chosen')) {
query = wcapfRemoveQueryStringParameter(filter_key_min);
query = wcapfRemoveQueryStringParameter(filter_key_max, query);
if (query == '') {
query = window.location.href.split('?')[0];
}
history.pushState({}, '', query);
} else {
query = wcapfUpdateQueryStringParameter(filter_key_min, filter_val_min, false);
query = wcapfUpdateQueryStringParameter(filter_key_max, filter_val_max, true, query);
}
// filter products
wcapfFilterProducts();
});
// handle the pagination request
if (wcapf_params.pagination_container.length > 0) {
var holder = wcapf_params.pagination_container + ' a';
$(document).on('click', holder, function(event) {
event.preventDefault();
var location = $(this).attr('href');
history.pushState({}, '', location);
// filter products
wcapfFilterProducts();
});
}
// history back and forward request handling
$(window).bind('popstate', function(event) {
// filter products
wcapfFilterProducts();
});
// ordering
wcapfInitOrder = function() {
if (typeof wcapf_params.sorting_control !== 'undefined' && wcapf_params.sorting_control.length && wcapf_params.sorting_control == true) {
$('.wcapf-before-products').find('.woocommerce-ordering').each(function(index) {
$(this).on('submit', function(event) {
event.preventDefault();
});
$(this).on('change', 'select.orderby', function(event) {
event.preventDefault();
var order = $(this).val(),
filter_key = 'orderby';
// change url
wcapfUpdateQueryStringParameter(filter_key, order);
// filter products
wcapfFilterProducts();
});
});
}
}
// init ordering
wcapfInitOrder();
// remove active filters
$(document).on('click', '.wcapf-active-filters a:not(.reset)', function(event) {
event.preventDefault();
var element = $(this),
filter_key = element.attr('data-key'),
filter_val = element.attr('data-value');
if (typeof filter_val === 'undefined') {
var query = wcapfRemoveQueryStringParameter(filter_key);
history.pushState({}, '', query);
// price slider
if ($('#wcapf-noui-slider').length && jQuery().noUiSlider) {
var priceSlider = document.getElementById('wcapf-noui-slider'),
min_val = parseInt($(priceSlider).attr('data-min')),
max_val = parseInt($(priceSlider).attr('data-max'));
if (min_val && max_val) {
if (filter_key === 'min-price') {
priceSlider.noUiSlider.set([min_val, null]);
} else if (filter_key === 'max-price') {
priceSlider.noUiSlider.set([null, max_val]);
}
}
}
// filter products
wcapfFilterProducts();
} else {
wcapfMakeParameters(filter_key, filter_val);
}
});
// clear all filters
$(document).on('click', '.wcapf-active-filters a.reset', function(event) {
event.preventDefault();
var location = $(this).attr('data-location');
history.pushState({}, '', location);
// filter products
wcapfFilterProducts();
});
// dispaly type dropdown
function formatState(state) {
var depth = $(state.element).attr('data-depth'),
$state = $('<span class="depth depth-' + depth + '">' + state.text + '</span>');
return $state;
}
wcapfDropDownFilter = function() {
if ($('.wcapf-select2-single').length) {
$('.wcapf-select2-single').select2({
templateResult: formatState,
minimumResultsForSearch: Infinity,
allowClear: true
});
}
if ($('.wcapf-select2-multiple').length) {
$('.wcapf-select2-multiple').select2({
templateResult: formatState,
});
}
$('.select2-dropdown').css('display', 'none');
}
// initialize dropdown filter
wcapfDropDownFilter();
$(document).on('change', '.wcapf-select2', function(event) {
event.preventDefault();
var filter_key = $(this).attr('name'),
filter_val = $(this).val();
if (!filter_val) {
var query = wcapfRemoveQueryStringParameter(filter_key);
history.pushState({}, '', query);
} else {
filter_val = filter_val.toString();
wcapfUpdateQueryStringParameter(filter_key, filter_val);
}
// filter products
wcapfFilterProducts();
});
});
我解决了这个问题。解决方案是在
event.stopPropagation();
函数之外添加 event.preventDefault();
到代码的以下部分:
// handle the filter request
$('.wcapf-ajax-term-filter').not('.wcapf-price-filter-widget').on('click', 'li a', function(event) {
event.preventDefault();
event.stopPropagation(); // Added to solve the problem!
var element = $(this),
filter_key = element.attr('data-key'),
filter_val = element.attr('data-value'),
enable_multiple_filter = element.attr('data-multiple-filter');
if (enable_multiple_filter == true) {
wcapfMakeParameters(filter_key, filter_val);
} else {
wcapfSingleFilter(filter_key, filter_val);
}
});