我正在构建一个 AJAX 实时搜索页面。到目前为止,一切都按预期运行,但我注意到我正在进行大量的 AJAX 调用。
我知道发生这种情况的地点和原因,但我找不到阻止这些 AJAX 调用发生的方法。
我将尝试给出快速解释,然后粘贴下面的代码。
在页面的左侧,我有一堆过滤器(例如位置、半径、兴趣、参与度、日期范围等)。它们中的每一个都有一个事件侦听器(例如更改)。当其中一个侦听器被触发时,我会更新查询参数并通过 AJAX 请求结果。
现在,当某人选择了 10 个兴趣(其中有 36 个),然后他分享 URL 时,就会出现问题,它看起来像这样:
现在首先,我会说我正在使用 iCheck.js 作为我的复选框。这意味着对“ifChecked”事件进行检查。
由于列表包含 10 个兴趣条目,因此“ifChecked”事件将被触发 10 次,从而导致 10 个 AJAX 请求。现在将其与 5 个 SDG、2 个参与、3 个位置……结合起来考虑,我最终会收到大量 AJAX 请求。
同时删除我的所有兴趣(有一个“删除”链接)时,它将触发“ifUnchecked”事件 10 次,从而再次执行 10 个 AJAX 请求。
这是我完整的 JS 代码,我尝试使用 HTML 等创建一个 jsfiddle,但代码与 CodeIgniter 框架有点混合,很难放置在那里。但 JS 代码足以让大家理解。
//Set vars available to entire scope for filtering
var searchLocation = null;
var searchRadius = 0;
var searchMin = 0;
var searchMax = 1000;
var searchMinPrice = 0;
var searchMaxPrice = 50000;
var searchSelectedInterests = [];
var searchSelectedSdgs = [];
var searchStartDate = moment().format('YYYY-MM-DD');
var searchEndDate = moment().add(1, 'years').format('YYYY-MM-DD');
var searchSelectedEngagements = [];
var getUrl = window.location;
var baseUrl = getUrl .protocol + "//" + getUrl.host + "/" + getUrl.pathname.split('/')[1];
$(document).ready(function(){
'use strict';
// Square Checkbox & Radio
$('.skin-square input').iCheck({
checkboxClass: 'icheckbox_square-blue'
});
$('.searchinterests input').on('ifChecked', function(event) {
var interestid = event.target.value;
searchSelectedInterests.push(interestid);
updateURLParameters();
performSearch();
});
$('.searchinterests input').on('ifUnchecked', function(event) {
var interestid = event.target.value;
var arrayPos = $.inArray(interestid, searchSelectedInterests);
if (arrayPos > -1) {
searchSelectedInterests.splice(arrayPos, 1);
}
performSearch();
});
$('.searchsdgs input').on('ifChecked', function(event) {
var sdgid = event.target.value;
searchSelectedSdgs.push(sdgid);
updateURLParameters();
performSearch();
});
$('.searchsdgs input').on('ifUnchecked', function(event) {
var sdgid = event.target.value;
var arrayPos = $.inArray(sdgid, searchSelectedSdgs);
if (arrayPos > -1) {
searchSelectedSdgs.splice(arrayPos, 1);
}
performSearch();
});
$('.searchengagements input').on('ifChecked', function(event) {
var social_engagement_id = event.target.value;
searchSelectedEngagements.push(social_engagement_id);
updateURLParameters();
performSearch();
});
$('.searchengagements input').on('ifUnchecked', function(event) {
var social_engagement_id = event.target.value;
var arrayPos = $.inArray(social_engagement_id, searchSelectedEngagements);
if (arrayPos > -1) {
searchSelectedEngagements.splice(arrayPos, 1);
}
performSearch();
});
var searchLocationSelect = $('.stb-search-location');
var radiusSlider = document.getElementById('radius-slider');
var minMaxSlider = document.getElementById('min-max-slider');
var priceSlider = document.getElementById('price-slider');
var daterangepicker = $('#searchdaterange');
var curr_lang = $('#curr_lang').val();
switch(curr_lang) {
case 'nl':
moment.locale('nl');
daterangepicker.daterangepicker({
minDate: moment(),
startDate: moment(),
endDate: moment().add(1, 'years'),
ranges: {
'Volgende week': [moment(), moment().add(1, 'weeks')],
'Volgende maand': [moment(), moment().add(1, 'months')],
'Volgende 3 maanden': [moment(), moment().add(3, 'months')],
'Volgende 6 maanden': [moment(), moment().add(6, 'months')],
'Volgend jaar': [moment(), moment().add(1, 'years')]
},
alwaysShowCalendars: true,
locale: {
"customRangeLabel": "Vrije keuze",
"format": "DD-MM-YYYY"
}
});
break;
case 'en':
moment.locale('en');
daterangepicker.daterangepicker({
minDate: moment(),
startDate: moment(),
endDate: moment().add(1, 'years'),
ranges: {
'Next week': [moment(), moment().add(1, 'weeks')],
'Next month': [moment(), moment().add(1, 'months')],
'Next 3 months': [moment(), moment().add(3, 'months')],
'Next 6 months': [moment(), moment().add(6, 'months')],
'Next year': [moment(), moment().add(1, 'years')]
},
alwaysShowCalendars: true,
locale: {
"customRangeLabel": "Free choice",
"format": "DD-MM-YYYY"
}
});
break;
case 'fr':
moment.locale('fr');
daterangepicker.daterangepicker({
minDate: moment(),
startDate: moment(),
endDate: moment().add(1, 'years'),
ranges: {
'Semaine prochaine': [moment(), moment().add(1, 'weeks')],
'Mois prochain': [moment(), moment().add(1, 'months')],
'3 mois prochains': [moment(), moment().add(3, 'months')],
'6 mois prochains': [moment(), moment().add(6, 'months')],
'L\'année prochaine': [moment(), moment().add(1, 'years')]
},
alwaysShowCalendars: true,
locale: {
"customRangeLabel": "Libre choix",
"format": "DD-MM-YYYY"
}
});
break;
}
daterangepicker.on('hide.daterangepicker', function (ev, picker) {
var startdate = picker.startDate.format('YYYY-MM-DD');
var enddate = picker.endDate.format('YYYY-MM-DD');
setStartDate(startdate);
setEndDate(enddate);
updateURLParameters();
performSearch();
});
if (searchLocationSelect.length) {
searchLocationSelect.selectize({
create: false,
sortField: {
field: 'text',
direction: 'asc'
},
dropdownParent: 'body',
plugins: ['remove_button'],
onChange: function(value) {
setLocation(value);
var size = value.length;
if (size == 1) {
enableRadius(radiusSlider);
} else {
disableAndResetRadius(radiusSlider);
}
updateURLParameters();
performSearch();
}
});
}
noUiSlider.create(radiusSlider, {
start: [0],
step: 5,
range: {
'min': 0,
'max': 100
}
});
var radiusNodes = [
document.getElementById('radius-value')
];
// Display the slider value and how far the handle moved
// from the left edge of the slider.
radiusSlider.noUiSlider.on('update', function (values, handle, unencoded, isTap, positions) {
var value = values[handle];
radiusNodes[handle].innerHTML = Math.round(value);
});
radiusSlider.noUiSlider.on('set', function (value) {
setRadius(value);
updateURLParameters();
performSearch();
});
var minmax_slider_options = {
start: [0,1000],
behaviour: 'drag',
connect: true,
tooltips: [wNumb({
decimals: 0
}), wNumb({
decimals: 0
})],
range: {
'min': 0,
'max': 1000
},
step: 5
};
noUiSlider.create(minMaxSlider, minmax_slider_options);
var minMaxNodes = [
document.getElementById('minmax-lower-value'),
document.getElementById('minmax-upper-value')
];
// Display the slider value and how far the handle moved
// from the left edge of the slider.
minMaxSlider.noUiSlider.on('update', function (values, handle, unencoded, isTap, positions) {
var value = values[handle];
minMaxNodes[handle].innerHTML = Math.round(value);
});
minMaxSlider.noUiSlider.on('set', function (values) {
setMin(values[0]);
setMax(values[1]);
updateURLParameters();
performSearch();
});
var price_slider_options = {
start: [0,50000],
behaviour: 'drag',
connect: true,
tooltips: [wNumb({
decimals: 0
}), wNumb({
decimals: 0
})],
range: {
'min': 0,
'max': 50000
},
step: 250
};
noUiSlider.create(priceSlider, price_slider_options);
var priceNodes = [
document.getElementById('price-lower-value'), // 1000
document.getElementById('price-upper-value') // 3500
];
// Display the slider value and how far the handle moved
// from the left edge of the slider.
priceSlider.noUiSlider.on('update', function (values, handle, unencoded, isTap, positions) {
var value = values[handle];
priceNodes[handle].innerHTML = '€'+Math.round(value);
});
priceSlider.noUiSlider.on('set', function (values) {
setMinPrice(values[0]);
setMaxPrice(values[1]);
updateURLParameters();
performSearch();
});
/** Reset methods **/
$('#resetLocations').on('click', function(e) {
e.preventDefault();
var locationInputField = $('.stb-search-location');
var control = locationInputField[0].selectize;
control.clear();
});
$('#resetRadius').on('click', function(e) {
e.preventDefault();
document.getElementById('radius-slider').noUiSlider.set(0);
});
$('#resetMinMax').on('click', function(e) {
e.preventDefault();
document.getElementById('min-max-slider').noUiSlider.set([0,1000]);
});
$('#resetPrice').on('click', function(e) {
e.preventDefault();
document.getElementById('price-slider').noUiSlider.set([0,50000]);
});
$('#resetInterests').on('click', function(e) {
e.preventDefault();
searchSelectedInterests = [];
$("input[name='interests[]']").iCheck('uncheck');
});
$('#resetSdgs').on('click', function(e) {
e.preventDefault();
searchSelectedSdgs = [];
$("input[name='sdgs[]']").iCheck('uncheck');
});
$('#resetDate').on('click', function(e) {
e.preventDefault();
$('#searchdaterange').data('daterangepicker').setStartDate(moment());
$('#searchdaterange').data('daterangepicker').setEndDate(moment().add(1, 'years'));
var startdate = $('#searchdaterange').data('daterangepicker').startDate.format('YYYY-MM-DD');
var enddate = $('#searchdaterange').data('daterangepicker').endDate.format('YYYY-MM-DD');
setStartDate(startdate);
setEndDate(enddate);
performSearch();
});
$('#resetEngagement').on('click', function(e) {
e.preventDefault();
searchSelectedEngagements = [];
$("input[name='engagement[]']").iCheck('uncheck');
});
// Set initial parameters (and pre-fill the filters based on query params)
setupConfig(radiusSlider);
});
function getQueryStringValue(){
var currentURL = new URI();
var queryParams = currentURL.query(true);
if ($.isEmptyObject(queryParams) === false) {
return queryParams;
} else {
return undefined;
}
}
//In here we read the query parameters from the URL and set the filters to the query parameters (+ do initial filtering)
function setupConfig(radiusSlider) {
var queryParams = getQueryStringValue();
if (queryParams !== undefined) {
var locations = queryParams.locations;
if (locations !== undefined) {
var locationsArray = locations.split(";");
fillLocations(locationsArray);
if (locationsArray.length != 1) {
disableAndResetRadius(radiusSlider);
}
} else {
disableAndResetRadius(radiusSlider);
}
var distance = queryParams.distance;
if (distance !== undefined) {
if (locationsArray.length != 1) {
disableAndResetRadius(radiusSlider);
} else {
document.getElementById('radius-slider').noUiSlider.set(distance);
}
}
var minEmployees = queryParams.minemployees;
var maxEmployees = queryParams.maxemployees;
if ((minEmployees !== undefined) && (maxEmployees !== undefined)) {
document.getElementById('min-max-slider').noUiSlider.set([minEmployees,maxEmployees]);
}
var minPrice = queryParams.minprice;
var maxPrice = queryParams.maxprice;
if ((minPrice !== undefined) && (maxPrice !== undefined)) {
document.getElementById('price-slider').noUiSlider.set([minPrice,maxPrice]);
}
var interests = queryParams.interests;
if (interests !== undefined) {
var interestsArray = interests.split(";");
fillInterests(interestsArray);
}
var sdgs = queryParams.sdgs;
if (sdgs !== undefined) {
var sdgsArray = sdgs.split(";");
fillSdgs(sdgsArray);
}
var startdate = queryParams.startdate;
var enddate = queryParams.enddate;
if ((startdate !== undefined) && (enddate !== undefined)) {
$('#searchdaterange').data('daterangepicker').setStartDate(moment(startdate));
$('#searchdaterange').data('daterangepicker').setEndDate(moment(enddate));
var startdate = $('#searchdaterange').data('daterangepicker').startDate.format('YYYY-MM-DD');
var enddate = $('#searchdaterange').data('daterangepicker').endDate.format('YYYY-MM-DD');
setStartDate(startdate);
setEndDate(enddate);
}
var engagements = queryParams.engagements;
if (engagements !== undefined) {
var engagementsArray = engagements.split(";");
fillEngagements(engagementsArray);
}
} else {
disableAndResetRadius(radiusSlider);
performSearch();
}
}
function fillLocations(locations) {
var selectize = $('.stb-search-location');
selectize[0].selectize.setValue(locations);
}
function fillInterests(interests) {
for (var i = 0; i < interests.length; i++) {
var checkboxId = "interest-"+interests[i];
var checkbox = $('#'+checkboxId);
checkbox.iCheck('check');
}
}
function fillSdgs(sdgs) {
for (var i = 0; i < sdgs.length; i++) {
var checkboxId = "sdg-"+sdgs[i];
var checkbox = $('#'+checkboxId);
checkbox.iCheck('check');
}
}
function fillEngagements(engagements) {
for (var i = 0; i < engagements.length; i++) {
var checkboxId = "eng-"+engagements[i];
var checkbox = $('#'+checkboxId);
checkbox.iCheck('check');
}
}
function getCurrLang() {
return $('#curr_lang').val();
}
function getCurrLangSegment() {
return $('#curr_abbr').val();
}
function getLocation() {
return $('#location').val();
}
function setLocation(value) {
searchLocation = value;
}
function setRadius(value) {
searchRadius = value;
}
function disableAndResetRadius(radiusSlider) {
radiusSlider.noUiSlider.set(0);
radiusSlider.setAttribute('disabled', true);
}
function enableRadius(radiusSlider) {
radiusSlider.removeAttribute('disabled');
}
function setMin(value) {
searchMin = value;
}
function setMax(value) {
searchMax = value;
}
function setMinPrice(value) {
searchMinPrice = value;
}
function setMaxPrice(value) {
searchMaxPrice = value;
}
function setStartDate(value) {
searchStartDate = value;
}
function setEndDate(value) {
searchEndDate = value;
}
function performSearch() {
$('#stb-items-placeholder').html('<div id="loading"><span>'+res.StbSearchPlaceholder+'</span></div>');
var searchOptions = {
type: 'POST',
url: baseUrl + '/dashboard/socialteambuildings/search/getFilteredStbs',
dataType: 'json'
};
var filterdata = {
"curr_lang" : getCurrLang(),
"curr_abbr" : getCurrLangSegment(),
"location" : getLocation(),
"interests": searchSelectedInterests,
"sdgs": searchSelectedSdgs
};
var options = $.extend({}, searchOptions, {
data: filterdata
});
// ajax done & fail
$.ajax(options).done(function (data) {
var mustacheJsonData = data.result;
var html = Mustache.render( $('#stbItemGen').html(), mustacheJsonData );
$('#stb-items-placeholder').html( html );
});
}
function updateURLParameters() {
if (searchLocation != null) {
var locationsUrlString = searchLocation.join(";");
}
var distanceUrlString = Math.round(searchRadius[0]);
var minEmployeesUrlString = Math.round(searchMin);
var maxEmployeesUrlString = Math.round(searchMax);
var minPriceUrlString = Math.round(searchMinPrice);
var maxPriceUrlString = Math.round(searchMaxPrice);
var interestUrlString = searchSelectedInterests.join(";");
var sdgUrlString = searchSelectedSdgs.join(";");
var startDateUrlString = searchStartDate;
var endDateUrlString = searchEndDate;
var engagementUrlString = searchSelectedEngagements.join(";");
var params = {locations: locationsUrlString, distance: distanceUrlString, minemployees: minEmployeesUrlString, maxemployees: maxEmployeesUrlString, minprice: minPriceUrlString, maxprice: maxPriceUrlString, interests: interestUrlString, sdgs: sdgUrlString, startdate: startDateUrlString, enddate: endDateUrlString, engagements: engagementUrlString};
var query = $.param(params);
addURLParameter(query);
}
//This function removes all the query parameters and adds the completely newly built query param string again
function addURLParameter(queryString){
var currentUrl = window.location.href;
var urlNoQueryParams = currentUrl.split("?");
var baseUrl = urlNoQueryParams[0];
var result = baseUrl + "?" + queryString;
window.history.replaceState('', '', result);
}
例如,我尝试在删除选项上使用 e.stopPropagation() 和 e.stopImmediatePropagation() 。这不会阻止事件返回 iCheck 库。