简体   繁体   English

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

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

In JavaScript we can create <style> element dynamically and append to <head> section in order to apply CSS rule for huge number of elements. 在JavaScript中,我们可以动态创建<style>元素并追加到<head>部分,以便对大量元素应用CSS规则。

  1. What is advantages or disadvantages of this approach? 这种方法的优点或缺点是什么?

  2. If it is really gives performance gain comparing to javascript iteration over elements. 如果确实比通过元素进行javascript迭代可以提高性能。 What goes behind the scene (inside of browser)? 幕后发生了什么(浏览器内部)?

  3. Which one is faster or slower? 哪一个更快或更慢? Javascript iteration over elements or adding css dynamically in browser? Javascript遍历元素或在浏览器中动态添加CSS?

  4. What about processing time? 那么处理时间呢? processing load? 处理负荷?

For better understanding the issue where I used this approach see following example: 为了更好地理解使用此方法的问题,请参见以下示例:

Example: If I have table with 20 or more columns and 1000 rows or more as following html: 示例:如果我有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>

If somebody needs jsFiddle example I can create one later. 如果有人需要jsFiddle示例,我可以稍后创建。

Case 1: If i want to dynamically hide only table column which contain SSN data. 情况1:如果我只想动态隐藏仅包含SSN数据的表列。 I can apply several approach to do this. 我可以采用几种方法来做到这一点。 This approach can be divided into two major category. 这种方法可以分为两大类。 In first category solutions I can iterate over td elements and dynamically change the style for the column. 第一类解决方案中,我可以遍历td元素并动态更改列的样式。 In second approach I can apply CSS by dynamically creating oneor use predefined CSS rules as given here by @Frits van Campen . 第二种方法中,我可以通过动态创建一个或使用@Frits van Campen 在此给出的预定义CSS规则来应用CSS。 ( Note: @Frits van Campen is good solution for given case. But I want to discuss further more then manipulating table row showing and hiding.) 注意: @Frits van Campen是给定情况的好解决方案。但是我想讨论更多然后处理表行的显示和隐藏。)

I can create dynamic CSS rule as following: 我可以创建动态CSS规则,如下所示:

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

Or apply predefined CSS rule: 或应用预定义的CSS规则:

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

Here are jsFiddly examples: 这是jsFiddly示例:

  1. Iteration 迭代
  2. CSS on fly 即时CSS

Here is time comparison using console.time method which I found here . 这是我在这里找到的使用console.time方法的时间比较。 在此处输入图片说明

Left is dynamic css and right is iteration approach. 左为动态CSS,右为迭代方法。

Perhaps, it is not appropriate one because it calculates appending style element vs iterating over elements. 也许这是不合适的,因为它计算追加样式元素与迭代元素。 All iteration over element in dynamic CSS will be done by browsers internals. 动态CSS中所有元素上的迭代都将由浏览器内部完成。 However if we think our script response time dynamic css is faster. 但是,如果我们认为脚本响应时间动态css更快。 Note : iteration approach will be faster in pure JavaScript comparing to jQuery. 注意 :与jQuery相比,在纯JavaScript中迭代方法会更快。 But how much faster i do not have results. 但是我没有结果快多少。 So you can more in your answers. 这样您就可以得到更多答案。

Case 2: Now, I want to highlight table row <tr> which contains user with name 'Nick'. 情况2:现在,我要突出显示表行<tr> ,其中包含名为“ Nick”的用户。 Here you can note that table row has data attributes like name, family_name, id and etc. So, here again I can iterate over elements using javascript or any other library tools or can apply some dynamic rule (I do not know whether it is possible or not apply predefined filters as in case 1.) 在这里,您可以注意到表格行具有数据属性,例如名称,family_name,id等。因此,在这里,我可以再次使用javascript或任何其他库工具遍历元素,或者可以应用一些动态规则(不知道是否可以还是不像情况1那样应用预定义的过滤器。)

CSS rule: CSS规则:

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

In this case I can do a lot of fun filtering by applying CSS rule dynamically. 在这种情况下,我可以通过动态应用CSS规则进行很多有趣的过滤。

Update: Example given here is for simple overview of the problem. 更新:此处给出的示例仅用于简单概述问题。 And some optimized iterations can perform equally fast in javascript. 而且一些优化的迭代可以在javascript中同样快地执行。 However I consider only table which does not have dipper child elements comparatively nested ul elements where traversing in order to select element can be difficult. 但是,我只考虑不包含北斗七星子元素且嵌套ul元素相对较多的表,在其中遍历以便选择元素可能很困难。

Important: I only give tabel example here to make clarification with what kind of issue I faced if it is irrelevant feel free to edit the question and delete this part. 重要提示:我仅在此处提供表格示例,以澄清与无关紧要时遇到的问题类型,可以随意编辑问题并删除此部分。 Also please state your answers clearly in scope of question. 另外,请在问题范围内清楚说明您的答案。 Here I am not asking about 'Did I implemented in good way or not?' 在这里,我不是在问“我实施得好吗?” I am asking what is of advantages or disadvantages of dynamically creating style elements has in terms of browser internal mechanisms. 我想问一下,动态创建样式元素在浏览器内部机制方面有什么优点或缺点。

PS and example: Why I came with this idea? PS和示例:为什么我想到这个主意? I answer recently for ' How to hide columns in very long html table ' question. 我最近回答“ 如何在很长的html表中隐藏列 ”问题。 In this question OP asks about applying CSS rule for certain table columns in long table. 在这个问题中,OP询问有关对长表中的某些表列应用CSS规则的问题。 I suggest to create style element with rules on fly and it works fine. 我建议创建带有规则的样式元素,并且效果很好。 I think this is because style applied by browsers internal mechanisms and gives better performance than iterating through elements and applying style to each item. 我认为这是因为样式是由浏览器的内部机制应用的,并且比迭代遍历元素并将样式应用于每个项目提供了更好的性能。

Apart from some scoping issues (there might be more tables on the page...) there is nothing inherently wrong with this approach - the style elements are there in the DOM to be edited as you see fit, the browsers are following standards by respecting it. 除了一些范围界定问题(页面上可能有更多表格...)之外,这种方法也没有本质上的错误-DOM中的style元素可以按您认为合适的方式进行编辑,浏览器遵循标准它。 In your test case, there's not really a valid other approach since indeed colgroup has extremely messy support - there are 78 duplicate bugs on the subject in Bugzilla, and Mozilla has been refusing to implement it properly since the first related bug report in 1998 . 在您的测试用例中,实际上没有一种有效的其他方法,因为colgroup确实提供了极为混乱的支持colgroup有78个关于该主题的重复错误,并且Mozilla自1998年第一个相关的错误报告以来一直拒绝正确实施它。

The reason it's faster is simply one of overhead - once the complete DOM is assembled a relatively minor stylesheet can be applied in native C++ much faster than a Javascript interpreter can ever loop over all rows and cells. 更快的原因只是开销之一-一旦组装了完整的DOM,相对较小的样式表就可以以比Java解释器遍历所有行和单元格更快的速度在本机C ++中应用。 This is because historically CSS rules are applied in reverse, and the browser keeps a dictionary inside quickly allowing it to find all td elements. 这是因为从历史上讲,CSS规则是反向应用的,并且浏览器将字典保留在内部,从而可以查找所有td元素。 Native C++ will always beat more complex interpreter-based code. 本机C ++将始终击败更复杂的基于解释器的代码。

In the future, the scoping issue can also be resolved with scoped styles (currently only in FF, rather typical), you'd be coding like this: 将来,范围问题也可以通过作用域样式解决(当前仅在FF中使用,这很典型),您将像这样进行编码:

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

The scoped attribute makes the contained styles only valid for its containing element , the table in this case, and of course all its contained elements. scoped属性使所包含的样式仅对其所包含的元素 (在这种情况下为table以及所有其所包含的元素有效。 And since you can access it by ID the contents are easily replaced/reconstructed. 并且由于您可以通过ID访问它,因此内容很容易替换/重构。

While this would be preferable to your approach, as long as there's no universal browser support for this creating style elements in the head is the best workaround. 尽管这比您的方法更好,但最好的解决方法是,只要没有通用的浏览器支持,在head创建style元素。

Dynamically generating CSS is bad . 动态生成CSS是不好的 Don't do it. 不要这样

A solution that works by generating dynamic CSS can converted to a solution that doesn't require dynamic CSS. 通过生成动态CSS起作用的解决方案可以转换为不需要动态CSS的解决方案。

If you need an example, see my answer here: jQuery to update actual CSS 如果您需要一个示例,请在这里查看我的答案: jQuery更新实际CSS


To respond directly about the case you linked: 要直接对您链接的案例做出回应:

This seems like a very strange use-case to me. 对我来说,这似乎是一个非常奇怪的用例。 A page that has a table with 1000 rows is already a bad starting position. 具有1000行表的页面的起始位置已经不好。 You can't reasonably fit 1000 rows on your screen and expect any kind of useful interaction. 您无法合理地在屏幕上容纳1000行,并且期望进行任何有用的交互。 CSS is not the problem here. CSS不是这里的问题。 If the table were smaller the performance concerns disappear. 如果表较小,则性能问题会消失。

There are possibly other approaches than the on OP suggests. 除了OP所建议的以外,可能还有其他方法。 You don't need to (dynamically) add a class to each cell, you can put the class there on generation time, like: 您不需要(动态地)向每个单元格添加类,您可以在生成时将类放在那里,例如:

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

Then have something like: 然后有类似的东西:

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

You only change the class on the table to say which filter applies. 您只需更改表上的类以说明适用哪个过滤器。

CSS is more than just a hammer, it's a whole tool-set of very refined and very powerful tools. CSS不只是锤子,它还是一个非常精致且功能强大的工具的完整工具集。 Make sure you use the right ones. 确保使用正确的。


The advantages of having static CSS should be self-apparent: 拥有静态CSS的优势应该是显而易见的:

  • Much easier to understand, test, debug and maintain. 更容易理解,测试,调试和维护。
  • The CSS is actually in CSS (not in JavaScript). CSS实际上是CSS(而不是JavaScript)。
  • You can do templating, maybe add some visual regression tests. 您可以做模板,也可以添加一些视觉回归测试。

There are also some performance concerns. 还存在一些性能问题。 I can see browser vendors optimizing AGAINST dynamic CSS. 我可以看到浏览器供应商优化了AGAINST动态CSS。 By this I mean if there is an optimization for static CSS that reduces performance of dynamic CSS you just might make this tradeoff. 我的意思是,如果对静态CSS进行了优化,从而降低了动态CSS的性能,那么您可能会做出权衡。

There's a library called less.js which lets you manipulate css with variables in in your.css file.It's a very good library and you might want to take a look into that. 有一个名为less.js的库,它使您可以使用.css文件中的变量来处理css,这是一个非常好的库,您可能需要研究一下。 http://www.lesscss.org/ http://www.lesscss.org/

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

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