Как прервать работу JavaScript на входе и начать новую операцию - PullRequest
0 голосов
/ 04 марта 2019

Я создал таблицу, но я использую <div> с вместо <tr> с и <td> с.Вот пример:

<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>
</div>

Я заполню tbody часть операциями на стороне сервера.

Я использую приведенные ниже коды для фильтрации своих строк на основе значений, введенных во входные данные фильтра.

$(".Filter").on('input', function () {
      filterGrid();
      $(".rowCount").val($(".tbody .tr:visible").length);
});
function filterGrid() {
    $('.tbody .tr').each(function () {
        var v = 1;
        var x = $(this);
        $(".thead .Filter[value!='']").each(function () {
            var i = $(this).parent(".td").index();
            if (x.children(".td:eq(" + i + ")").html().indexOf($(this).val()) == -1) {
                v = 0;
                x.hide();
                return false;
            }
        });
        if (v == 1) {
            x.show();
        }
    });
}

Мой код работает нормально, когда у меня несколько строк, но когда количество загруженных строк увеличивается, для выполнения операции фильтрации требуется больше времени.

при вводе первой буквы я не могу ввести вторую букву до окончания фильтрации по первой букве.могу ли я принудить JavaScript прервать операцию и начать новую при вводе?

ниже приведен пример моей таблицы

This is a sample of my table

1 Ответ

0 голосов
/ 04 марта 2019

У вас довольно много 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);
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...