【问题标题】:Filtering a table by element's name按元素名称过滤表格
【发布时间】:2020-06-20 18:33:54
【问题描述】:

我正在尝试通过在搜索表单中编写一些文本来过滤此 HTML 表格,效果很好,但每当过滤时,元素都会尝试填充表格的整个宽度,而不是保持其原始元素宽度(25%表格的宽度,不计算单元格之间的空间)。

function searchFilter () {
   const input = document.getElementById('myInput');
   const filter = input.value.toUpperCase();
   const table = document.getElementById('tablaPiola');
   const articule = table.getElementsByTagName('td');

   for (i = 0; i < articule.length; i++) {
      a = articule[i].getElementsByTagName("a")[0];
      txtValue = a.textContent || a.innerText;
      if (txtValue.toUpperCase().indexOf(filter) > -1) {
         articule[i].style.display = "";
         } else {
         articule[i].style.display = "none";
         }
   }
}

document.getElementById("filter-btn").addEventListener("click", searchFilter);
body {
background-color: black;
}

table
{border-spacing: 20px;
table-layout: fixed;
width: 600px;
margin: auto;
margin-top: 10px;}

td
{text-align: center;
border-radius: 10px;}

td a
{width: 100%;
display: block;
line-height: 50px;
text-decoration: none;
font-family: "Poppins";
font-weight: 700;
font-size: 12px;
color: white;}

.automatizaciones
{background-image: url("https://via.placeholder.com/100/0000FF/0000FF");
background-size: cover;}

.bpm_a_ms
{background-image: url("https://via.placeholder.com/100/0000FF/0000FF");
background-size: cover;}

.compresion
{background-image: url("https://via.placeholder.com/100/0000FF/0000FF");
background-size: cover;}

.compresion_multibanda
{background-image: url("https://via.placeholder.com/100/0000FF/0000FF");
background-size: cover;}
<input type="text" id="myInput">
<input type="button" id="filter-btn" value="Apply">
<table class="tabla_basico" id="tablaPiola">
   <tr>
      <td class="automatizaciones">
         <div class="overlay_basico"><a href="/">AUTOMATIZACIONES</a></div>
      </td>
      <td class="bpm_a_ms">
         <div class="overlay_intermedio"><a href="/">BPM A MS</a></div>
      </td>
      <td class="compresion">
         <div class="overlay_basico"><a href="compresion.html">COMPRESIÓN</a></div>
      </td>
      <td class="compresion_multibanda">
         <div class="overlay_intermedio"><a href="/">COMPRESIÓN MULTIBANDA</a></div>
       </td>
   </tr>
</table>

This is my webpage

This is how it filters

【问题讨论】:

  • 欢迎来到 Stack Overflow! 不错的一个,包括几乎所有相关的 HTML、CSS 和 JavaScript!我能够使用您提供的内容并使用 Stack Snippets([&lt;&gt;] 工具栏按钮)在您的问题中创建一个可运行的版本。下次,here's how to do one。同样,做得很好,包括几乎所有需要的东西,而且没有太多额外的东西。
  • 我只是好奇:那是什么语言?它看起来有点像我熟悉的几种语言,但又不太像其中任何一种。 :-) 您的位置支持巴西葡萄牙语,但如果我没记错的话,articule 将是 artigosarticule 看起来像是意大利语,但它会是 articoli。西班牙语不会使用这种复数形式。显然是一种浪漫的语言,但是……我只是好奇,我喜欢语言。
  • 我来自阿根廷布宜诺斯艾利斯,所以是西班牙语 :)
  • 我使用了一些英语单词和一些西班牙语单词。认为“articule”是“articulo”的英文(西班牙语):P
  • 啊!英文是“article”和“articles”:-D

标签: javascript html css filter width


【解决方案1】:

我原本以为visibility: hidden,但你指出这意味着显示的那些不再在左边了。

我唯一的另一个想法是在最后添加填充单元:

function searchFilter () {
   const input = document.getElementById('myInput');
   const filter = input.value.toUpperCase();
   const table = document.getElementById('tablaPiola');
   // Remove any fillers we added last time
   table.querySelectorAll(".filler").forEach(filler => {
       filler.parentNode.removeChild(filler);
   });
   const articule = table.getElementsByTagName('td');
   // Remember how many are showing at the end
   let showing = 0;

   for (i = 0; i < articule.length; i++) {
      a = articule[i].getElementsByTagName("a")[0];
      txtValue = a.textContent || a.innerText;
      if (txtValue.toUpperCase().indexOf(filter) > -1) {
         articule[i].style.display = "";
         ++showing; // Remember we're showing this one
      } else {
         articule[i].style.display = "none";
      }
   }
   // Grab the length (since `articule` is a live list
   const max = articule.length;
   // Add blank cells to the end
   while (showing < max) {
      const filler = document.createElement("td");
      filler.className = "filler";
      table.appendChild(filler);
      ++showing;
   }
}

现场示例:

function searchFilter () {
   const input = document.getElementById('myInput');
   const filter = input.value.toUpperCase();
   const table = document.getElementById('tablaPiola');
   // Remove any fillers we added last time
   table.querySelectorAll(".filler").forEach(filler => {
       filler.parentNode.removeChild(filler);
   });
   const articule = table.getElementsByTagName('td');
   // Remember how many are showing at the end
   let showing = 0;
   
   for (i = 0; i < articule.length; i++) {
      a = articule[i].getElementsByTagName("a")[0];
      txtValue = a.textContent || a.innerText;
      if (txtValue.toUpperCase().indexOf(filter) > -1) {
         articule[i].style.display = "";
         ++showing; // Remember we're showing this one
      } else {
         articule[i].style.display = "none";
      }
   }
   // Grab the length (since `articule` is a live list
   const max = articule.length;
   // Add blank cells to the end
   while (showing < max) {
      const filler = document.createElement("td");
      filler.className = "filler";
      table.appendChild(filler);
      ++showing;
   }
}

document.getElementById("filter-btn").addEventListener("click", searchFilter);
body {
background-color: black;
}

table
{border-spacing: 20px;
table-layout: fixed;
width: 1200px;
margin: auto;
margin-top: 100px;}

td
{text-align: center;
border-radius: 10px;}

td a
{width: 100%;
display: block;
line-height: 150px;
text-decoration: none;
font-family: "Poppins";
font-weight: 700;
font-size: 17.5px;
color: white;}

.automatizaciones
{background-image: url(imagenes/basico/automatizaciones/articulo.jpg);
background-size: cover;}

.bpm_a_ms
{background-image: url(imagenes/intermedio/bpm_a_ms/articulo.jpg);
background-size: cover;}

.compresion
{background-image: url(imagenes/basico/compresion/articulo.jpg);
background-size: cover;}

.compresion_multibanda
{background-image: url(imagenes/intermedio/compresion_multibanda/articulo.jpg);
background-size: cover;}
<input type="text" id="myInput">
<input type="button" id="filter-btn" value="Apply">
<table class="tabla_basico" id="tablaPiola">
   <tr>
      <td class="automatizaciones">
         <div class="overlay_basico"><a href="/">AUTOMATIZACIONES</a></div>
      </td>
      <td class="bpm_a_ms">
         <div class="overlay_intermedio"><a href="/">BPM A MS</a></div>
      </td>
      <td class="compresion">
         <div class="overlay_basico"><a href="compresion.html">COMPRESIÓN</a></div>
      </td>
      <td class="compresion_multibanda">
         <div class="overlay_intermedio"><a href="/">COMPRESIÓN MULTIBANDA</a></div>
       </td>
   </tr>
</table>

其他一些与主要问题没有直接关系的注释:

  • 该代码成为我所说的 The Horror of Implicit Globals 的牺牲品。您永远不会声明 iatxtValue,因此在分配给它们时最终会创建全局变量。我建议在所有代码中使用strict mode,这样当你尝试这样做时会出错。

  • FWIW,我看到您正在使用 ES2015+ 功能(例如const),因此您可以使用for-of 循环而不是for 循环。 for-of 打字少了一点。但是您可能需要在某些平台上填充可迭代性。我的回答 here 显示了如何做到这一点。

【讨论】:

  • 这在过滤方面效果很好,但我希望它们出现在表格的开头而不是停留在原来的表格位置。
  • 我来看看,我刚刚通过一些关于 codecademy 的课程学习了 JavaScript,所以我几乎是这个主题的初学者。是的,现在它们保持在 25%,这很酷。
  • 最后一次更新似乎在每一行都应用了一个唯一的过滤器,因此适用于条件的每个元素都会移动到每行的第一/第二/第三/第四 (如果有该行中最多 4 个元素应用于条件),而不是填充第一行,然后是第二行,等等。
  • @Sztraji - 恐怕我不明白你的意思。
  • 解决了这个问题,制作了一个全新的
    表格/网格,而不是一个实际的 ,所以我不必处理不同的行标签,而且效果很好! :) 感谢您的帮助
猜你喜欢
相关资源
最近更新 更多
热门标签