10

在 JavaScript 中,我们可以<style>动态创建元素并附加到<head>部分,以便将 CSS 规则应用于大量元素。

  1. 这种方法的优点或缺点是什么?

  2. 如果与元素上的 javascript 迭代相比,它确实可以提高性能。幕后(浏览器内部)发生了什么?

  3. 哪个更快或更慢?Javascript迭代元素或在浏览器中动态添加css?

  4. 处理时间呢?处理负载?

为了更好地理解我使用这种方法的问题,请参见以下示例:

示例:如果我有 20 列或更多列和 1000 行或更多行的表,如下 html:

<table border="1" class='no-filter'>
    <thead>
        <tr>
            <th data-title='id'>Id</th>
            <th data-title='name'>Name</th>
            <th data-title='family_name'>Family Name</th>
            <th data-title='ssn'>SSN</th>
            //Other table data
        </tr>
    </thead>
    <tbody>
        <tr data-id='1' data-name='nick' data-famil_name='jackson' data-ssn='123456'>
            <td class="column column1">1</td>
            <td class="column column2">Nick</td>
            <td class="column column3">Jackson</td>
            <td class="column column4">123456</td>
            //Other table data
        </tr>
        //Other rows
        <tr data-id='809' data-name='helga' data-famil_name='jhonson' data-ssn='125648'>
            <td class="column column1">809</td>
            <td class="column column2">Helga</td>
            <td class="column column3">Jhonson</td>
            <td class="column column4">125648</td>
            //Other table data
        </tr>
        //Other rows
        <tr data-id='1001' data-name='nick' data-famil_name='jhonson' data-ssn='216458'>
            <td class="column column1">1001</td>
            <td class="column column2">Nick</td>
            <td class="column column3">Jhonson</td>
            <td class="column column4">216458</td>
            //Other table data
        </tr>
        //Other rows
    </tbody>
</table>

如果有人需要 jsFiddle 示例,我可以稍后创建一个。

案例 1:如果我只想动态隐藏包含 SSN 数据的表列。我可以应用几种方法来做到这一点。这种方法可以分为两大类。在 第一类解决方案中,我可以迭代td元素并动态更改列的样式。在第二种方法中,我可以通过动态创建一个或使用@Frits van Campen在此处给出的预定义 CSS 规则来应用 CSS 。(注意:@Frits van Campen对于给定的情况是一个很好的解决方案。但我想进一步讨论操作表格行的显示和隐藏。)

我可以创建如下动态 CSS 规则:

td:nth-child(3)
{
  display:none;
}

或者应用预定义的 CSS 规则:

table.no-filter td.column3
{
   display:block;
}
table.filter3 td.column3 
{ 
   display: none; 
}

以下是 jsFiddly 示例:

  1. 迭代
  2. 动态 CSS

这是我在这里找到的使用 console.time 方法的时间比较。 在此处输入图像描述

左边是动态css,右边是迭代方法。

也许,这是不合适的,因为它计算附加样式元素与迭代元素。动态 CSS 中元素的所有迭代都将由浏览器内部完成。但是,如果我们认为我们的脚本响应时间动态 css 更快。注意:与 jQuery 相比,纯 JavaScript 中的迭代方法会更快。但是我没有结果有多快。所以你可以在你的答案更多。

案例 2:现在,我想突出显示<tr>包含名为“Nick”的用户的表行。在这里您可以注意到表格行具有名称、family_name、id 等数据属性。因此,在这里我可以再次使用 javascript 或任何其他库工具迭代元素,或者可以应用一些动态规则(我不知道是否可以或不应用预定义的过滤器,如案例 1。)

CSS 规则:

tr[data-name ~='nick']
{
    background-color:red;
}

在这种情况下,我可以通过动态应用 CSS 规则来做很多有趣的过滤。

更新:此处给出的示例是对问题的简单概述。一些优化的迭代可以在 javascript 中同样快速地执行。但是,我只考虑没有 dipper 子元素的表相对嵌套的 ul 元素,其中遍历以选择元素可能很困难。

重要提示:我在这里仅给出表格示例,以澄清我遇到的问题,如果无关紧要,请随时编辑问题并删除此部分。还请在问题范围内清楚地说明您的答案。在这里,我不是在问“我实施得好不好?” 我在问动态创建样式元素在浏览器内部机制方面有什么优点或缺点。

PS和例子:为什么我有这个想法?我最近回答了“如何在很长的 html 表格中隐藏列”的问题。在这个问题中,OP 询问有关对长表中的某些表列应用 CSS 规则的问题。我建议使用动态规则创建样式元素,并且效果很好。我认为这是因为样式由浏览器内部机制应用,并且比遍历元素并将样式应用于每个项目提供更好的性能。

4

3 回答 3

4

动态生成 CSS 是不好的。不要这样做。

通过生成动态 CSS 工作的解决方案可以转换为不需要动态 CSS 的解决方案。

如果您需要一个示例,请在此处查看我的答案:jQuery to update actual CSS


要直接回复您链接的案例:

这对我来说似乎是一个非常奇怪的用例。具有 1000 行表的页面已经是一个错误的起始位置。您无法合理地在屏幕上放置 1000 行并期望任何类型的有用交互。CSS 不是这里的问题。如果表更小,性能问题就会消失。

除了 on OP 建议的方法之外,可能还有其他方法。您不需要(动态)向每个单元格添加一个类,您可以在生成时间将类放在那里,例如:

<table class="no-filter">
...
  <td class="filter1 filter2"></td>
...
</table>

然后有类似的东西:

table.filter1 td.filter2 { display: none; }
table.filter2 td.filter1 { display: none; }

您只需更改表上的类以说明应用哪个过滤器。

CSS 不仅仅是一把锤子,它是一整套非常精致且非常强大的工具。确保使用正确的。


拥有静态 CSS 的优点应该是不言而喻的:

  • 更容易理解、测试、调试和维护。
  • CSS 实际上是在 CSS 中(而不是在 JavaScript 中)。
  • 你可以做模板,也许添加一些视觉回归测试。

还有一些性能问题。我可以看到浏览器供应商针对动态 CSS 进行优化。我的意思是,如果静态 CSS 的优化会降低动态 CSS 的性能,那么您可能会做出这种权衡。

于 2014-01-08T02:22:01.317 回答
4

除了一些范围问题(页面上可能有更多表格......)这种方法本质上没有任何问题 - styleDOM中的元素可以根据您的需要进行编辑,浏览器通过尊重它来遵循标准. 在您的测试用例中,没有真正有效的其他方法,因为确实有非常混乱的支持 - 在 Bugzilla 中有 78 个关于该主题的重复错误,自1998 年第一个相关错误报告colgroup以来,Mozilla 一直拒绝正确实施它。

它更快的原因仅仅是开销之一——一旦组装了完整的 DOM,就可以在原生 C++ 中应用相对较小的样式表,这比 Javascript 解释器遍历所有行和单元格的速度要快得多。这是因为从历史上看,CSS 规则是反向应用的,浏览器在内部保存了一个字典,可以快速找到所有td元素。本机 C++ 总是会击败更复杂的基于解释器的代码。

将来,范围问题也可以通过范围样式来解决(目前仅在 FF 中,相当典型),您将像这样编码:

<table>
  <style id="myTableStyle" scoped>
    td:nth-child(1) { display:none }
  </style>
  <tbody>
     ...
  </tbody>
</table>

scoped属性使包含的样式仅对其包含的元素有效,table在这种情况下,当然还有其所有包含的元素。而且由于您可以通过 ID 访问它,因此内容很容易替换/重建。

虽然这比您的方法更可取,但只要没有通用浏览器支持此创建style元素,这head是最好的解决方法。

于 2014-01-08T01:51:54.107 回答
-1

有一个名为 less.js 的库,它可以让您使用 .css 文件中的变量来操作 css。这是一个非常好的库,您可能想看看它。 http://www.lesscss.org/

于 2014-01-24T19:27:43.580 回答