[英]JavaScript: Advantages and disadvantages of dynamically (on fly) creating style element
在JavaScript中,我们可以动态创建<style>
元素并追加到<head>
部分,以便对大量元素应用CSS规则。
这种方法的优点或缺点是什么?
如果确实比通过元素进行javascript迭代可以提高性能。 幕后发生了什么(浏览器内部)?
哪一个更快或更慢? Javascript遍历元素或在浏览器中动态添加CSS?
那么处理时间呢? 处理负荷?
为了更好地理解使用此方法的问题,请参见以下示例:
示例:如果我有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示例:
这是我在这里找到的使用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的优势应该是显而易见的:
还存在一些性能问题。 我可以看到浏览器供应商优化了AGAINST动态CSS。 我的意思是,如果对静态CSS进行了优化,从而降低了动态CSS的性能,那么您可能会做出权衡。
有一个名为less.js的库,它使您可以使用.css文件中的变量来处理css,这是一个非常好的库,您可能需要研究一下。 http://www.lesscss.org/
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.