mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-10-26 08:36:12 +01:00
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
This commit is contained in:
@@ -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 () {
|
||||
|
||||
Reference in New Issue
Block a user