feat: #8813, faster category search dropdown

when you have 4k+ categories manipulating DOM becomes very slow
clone the list and manipulate it outside of DOM, replace list on DOM when search is done
add utils.debounce so list is updated slower
v1.18.x
Barış Soner Uşaklı 4 years ago
parent e3cd7a2343
commit 072a0e32d8

@ -14,18 +14,23 @@ define('categorySearch', function () {
var toggleVisibility = searchEl.parent('[component="category/dropdown"]').length > 0 ||
searchEl.parent('[component="category-selector"]').length > 0;
var categoryEls = el.find('[component="category/list"] [data-cid]');
var listEl = el.find('[component="category/list"]');
var clonedList = listEl.clone();
var categoryEls = clonedList.find('[data-cid]');
el.on('show.bs.dropdown', function () {
var cidToParentCid = {};
function revealParents(cid) {
var parentCid = el.find('[component="category/list"] [data-cid="' + cid + '"]').attr('data-parent-cid');
var parentCid = cidToParentCid[cid];
if (parentCid) {
el.find('[component="category/list"] [data-cid="' + parentCid + '"]').removeClass('hidden');
clonedList.find('[data-cid="' + parentCid + '"]').removeClass('hidden');
revealParents(parentCid);
}
}
function revealChildren(cid) {
var els = el.find('[component="category/list"] [data-parent-cid="' + cid + '"]');
var els = clonedList.find('[data-parent-cid="' + cid + '"]');
els.each(function (index, el) {
var $el = $(el);
$el.removeClass('hidden');
@ -39,12 +44,14 @@ define('categorySearch', function () {
var cids = [];
categoryEls.each(function () {
var liEl = $(this);
var isMatch = liEl.attr('data-name').toLowerCase().indexOf(val) !== -1;
var isMatch = cids.length < 100 && (!val || (val.length > 1 && liEl.attr('data-name').toLowerCase().indexOf(val) !== -1));
if (noMatch && isMatch) {
noMatch = false;
}
if (isMatch && val) {
cids.push(liEl.attr('data-cid'));
var cid = liEl.attr('data-cid');
cids.push(cid);
cidToParentCid[cid] = parseInt(liEl.attr('data-parent-cid'), 10);
}
liEl.toggleClass('hidden', !isMatch).find('[component="category-markup"]').css({ 'font-weight': val && isMatch ? 'bold' : 'normal' });
});
@ -54,6 +61,7 @@ define('categorySearch', function () {
revealChildren(cid);
});
listEl.html(clonedList.html());
el.find('[component="category/list"] [component="category/no-matches"]').toggleClass('hidden', !noMatch);
}
if (toggleVisibility) {
@ -65,7 +73,7 @@ define('categorySearch', function () {
ev.preventDefault();
ev.stopPropagation();
});
searchEl.find('input').val('').on('keyup', updateList);
searchEl.find('input').val('').on('keyup', utils.debounce(updateList, 200));
updateList();
});
el.on('shown.bs.dropdown', function () {

Loading…
Cancel
Save