У вас довольно много jQuery-операций, которые при объединении в несколько строк могут занимать немалое количество времени.Вместо того, чтобы создавать множество коллекций jQuery (которые имеют некоторые накладные расходы) и пересчитывать индекс, который вы ищете на каждой итерации, рассмотрите использование вместо этого ванильного Javascript, который гораздо более легок.Вы также можете заранее создать массив значений фильтров и связанных с ними индексов, чтобы вам не приходилось перемещаться по DOM, чтобы найти их на каждой итерации:
$(".Filter").on('input', function() {
$(".rowCount").val(filterGrid());
});
function filterGrid() {
const values = Array.from(
document.querySelectorAll('.thead .Filter'),
elm => elm.value
);
let rowsShown = 0;
document.querySelectorAll('.tbody .tr').forEach((tr) => {
const tds = tr.querySelectorAll('.td');
const noMatch = values.some((value, i) => {
if (!value) {
return;
}
const td = tds[i];
return !td.innerHTML.includes(value);
});
if (noMatch) {
tr.style.display = 'none';
} else {
tr.style.display = 'block';
rowsShown++;
}
});
return rowsShown;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
RowCount: <span class="rowCount">1</span>
<div class="tbl tbl1">
<div class="thead">
<div class="tr">
<div class="td colTitle" style="width: 120px"><span>Title</span></div>
<div class="td colLink" style="width: 190px"><span>Link</span></div>
<div class="td colSize numeric" style="width: 75px"><span>Size(MB)</span></div>
<div class="td colUploadDate" style="width: 75px"><span>UploadDate</span></div>
<div class="td colOpen" style="width: 50px; max-width: 50px;"><span>Show</span></div>
</div>
<div class="tr">
<div class="td colTitle">
<input type="text" class="Filter" />
</div>
<div class="td colLink">
<input type="text" class="Filter" />
</div>
<div class="td colSize">
<input type="text" class="Filter" />
</div>
<div class="td colUploadDate">
<input type="text" class="Filter" />
</div>
<div class="td colOpen">
</div>
</div>
</div>
<div class="tbody">
<div class="tr" idattachment="1">
<div class="td colTitle" style="width: 120px;">FirstFile</div>
<div class="td colLink" style="width: 190px;">uf1_1.png</div>
<div class="td colSize" style="width: 75px;">0.11</div>
<div class="td colUploadDate" style="width: 75px;">1397/12/13</div>
<div class="td colOpen" style="width: 50px;"><a class="link" href="uploads/uf1_1.png">Open</a></div>
</div>
</div>
</div>
Если этого недостаточно, вы можете использовать циклы for
вместо методов массива, что сделает вещи немного быстрее (хотя и труднее читать).
Если у вас есть огромное количество строк в .tbody
, и это все еще не достаточно быстро, то вы можете рассмотреть возможность добавления debouncer к слушателю input
, поэтомучто filterGrid
вызывается только, скажем, через 200 мс после ввода последнего символа, так что большая операция происходит только тогда, когда у вас есть хотя бы бит уверенности в том, что только что набранный символ может бытьпоследний, который пользователь хочет ввести (вместо запуска filterGrid
после каждого введенного символа):
let filterTimeout;
$(".Filter").on('input', function() {
clearTimeout(filterTimeout);
filterTimeout = setTimeout(() => {
$(".rowCount").val(filterGrid());
}, 200);
});