如何在输入时中断javascript操作并开始新操作 [英] How to break javascript operation on input and start new operation

查看:48
本文介绍了如何在输入时中断javascript操作并开始新操作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经生成了一个表,但是我使用的是<div> s而不是<tr> s和<td> s.这是一个示例:

I have produced a table but I am using <div>s instead of <tr>s and <td>s. here is an example:

<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部分.

I will fill tbody part with server-side operations.

我使用以下代码根据在过滤器输入中输入的值过滤行.

I use below codes to filter my rows based on values entered in filter inputs.

$(".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();
        }
    });
}

当行数很少时,我的代码可以正常工作,但是当加载的行数增加时,执行过滤操作将花费更多时间.

My code works fine when I have a few number of rows, but when the number of loaded rows increases it takes more time to do filtering operation.

当我输入第一个字母时,直到基于第一个字母的过滤结束,我才能输入第二个字母.键入时,我可以强制执行javascript来中断操作并开始一个新操作吗?

when I enter the first letter I can't enter the second letter until the end of filtering based on the first letter. can I enforce javascript to break the operation and start a new one when I type ?

下面是我的桌子的一个例子

below is a sample of my table

推荐答案

您有很多jQuery操作,将它们组合成多行后,可能会花费不小的时间.与其构建大量的jQuery集合(有一些开销)并在每次迭代中重新计算您要寻找的索引,不如考虑使用香草Javascript,这要轻得多.您还可以预先创建一个包含过滤器值及其相关索引的数组,因此您不必浏览DOM即可在每次迭代中找到它们:

You have quite a lot of jQuery operations that, when put together over many rows, may take a not-insignificant amount of time. Rather than constructing lots of jQuery collections (which have some overhead) and re-calculating the index you're looking for on every iteration, consider using vanilla Javascript instead, which is far more lightweight. You can also create an array of the filter values and their associated index in advance, so you don't have to navigate through the DOM to find them every iteration:

$(".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循环而不是数组方法,这会使处理速度更快(尽管更难于阅读).

If that's not fast enough, you can use for loops instead of array methods, which will make things a bit faster (though more difficult to read).

如果.tbody中的行数巨大,而这仍然不够快,那么您可以考虑在input侦听器中添加一个去抖器,以便仅在输入最后一个字符后200毫秒后才调用,因此只有在您至少有 bit 确信刚键入的字符可能是最后一个字符后,才进行大操作用户想要输入的一个字符(而不是在键入每个单个字符后运行filterGrid):

If you have a huge number of rows in the .tbody and this still isn't fast enough, then you might consider adding a debouncer to the input listener, so that filterGrid is only called after, say, 200ms after the last character was typed, so that the big operation only occurs once you have at least a bit of confidence that the character that was just typed might be the last one the user wants to input (rather than running filterGrid after every single character typed):

let filterTimeout;
$(".Filter").on('input', function() {
  clearTimeout(filterTimeout);
  filterTimeout = setTimeout(() => {
    $(".rowCount").val(filterGrid());
  }, 200);
});

这篇关于如何在输入时中断javascript操作并开始新操作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆