繁体   English   中英

JavaScript:动态(动态)创建样式元素的优缺点

[英]JavaScript: Advantages and disadvantages of dynamically (on fly) creating style element

在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中同样快地执行。 但是,我只考虑不包含北斗七星子元素且嵌套ul元素相对较多的表,在其中遍历以便选择元素可能很困难。

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

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

除了一些范围界定问题(页面上可能有更多表格...)之外,这种方法也没有本质上的错误-DOM中的style元素可以按您认为合适的方式进行编辑,浏览器遵循标准它。 在您的测试用例中,实际上没有一种有效的其他方法,因为colgroup确实提供了极为混乱的支持colgroup有78个关于该主题的重复错误,并且Mozilla自1998年第一个相关的错误报告以来一直拒绝正确实施它。

更快的原因只是开销之一-一旦组装了完整的DOM,相对较小的样式表就可以以比Java解释器遍历所有行和单元格更快的速度在本机C ++中应用。 这是因为从历史上讲,CSS规则是反向应用的,并且浏览器将字典保留在内部,从而可以查找所有td元素。 本机C ++将始终击败更复杂的基于解释器的代码。

将来,范围问题也可以通过作用域样式解决(当前仅在FF中使用,这很典型),您将像这样进行编码:

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

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

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

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

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

如果您需要一个示例,请在这里查看我的答案: jQuery更新实际CSS


要直接对您链接的案例做出回应:

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

除了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)。
  • 您可以做模板,也可以添加一些视觉回归测试。

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

有一个名为less.js的库,它使您可以使用.css文件中的变量来处理css,这是一个非常好的库,您可能需要研究一下。 http://www.lesscss.org/

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM