我有一个表,我显示/隐藏一个完整的列由jQuery通过CSS类不存在:
<table>
<thead>
<tr>
<th></th>
<th class="target"></th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td></td>
<td class="target"></td>
<td></td>
</tr>
<tr>
<td></td>
<td class="target"></td>
<td></td>
</tr>
</tbody>
</table>
有了这个DOM,我可以在一行通过jQuery: $('.target').css('display','none');
这是完美的工作,但它是有效的使用CSS类没有定义?我应该为它创建一个空类吗?
<style>.target{}</style>
有没有副作用或者有没有更好的方法?
“CSS类”是一个用词不当;class是分配给HTML元素的属性(从脚本的角度来说,是属性)。换句话说,您在HTML中声明类,而不是在CSS中声明类,因此在您的情况下,“目标”类实际上存在于那些特定的元素上,并且您的标记是完全有效的。
这并不意味着你必须在HTML中声明一个类,然后才能在CSS中使用它。请看ruakh的评论。选择器是否有效完全取决于选择器语法,CSS有自己的一组处理解析错误的规则,这些规则与标记无关。从本质上讲,这意味着HTML和CSS在有效性方面是完全独立的
一旦您理解了这一点,就可以清楚地看到在样式表中不定义.target规则不会产生任何副作用当您将类分配给元素时,您可以通过样式表或脚本中的类引用这些元素。双方都不依赖对方。相反,它们都引用标记(或者更准确地说,它的DOM表示)。即使使用JavaScript来应用样式,这个原则也适用,就像在jQuery一行程序中所做的那样。
当您使用类选择器编写CSS规则时,您所说的一切都是“我想将样式应用于属于该类的元素”。类似地,当您编写一个脚本来根据某个类名检索元素时,您就是在说“我想对属于这个类的元素做一些事情”。是否有元素属于所讨论的类完全是一个单独的问题。
1这也是为什么CSS ID选择器匹配所有给定ID的元素,而不管ID是只出现一次,还是多次出现(导致HTML文档不符合要求)。
我所知道的唯一一种情况是,当一些浏览器因为bug而拒绝正确应用某些其他规则时,这样的空CSS规则是必要的;创建空规则将导致出于某种原因应用其他规则。有关此类错误的示例,请参见下面的回答。然而,这是在CSS方面,因此应该与标记无关。
这里没有人完全提到的一件事是JavaScript(在本例中由jQuery辅助)不能直接修改文档的级联样式表。jQuery的css()方法仅仅改变匹配的元素的style属性集。CSS和JavaScript在这方面是完全不相关的。
$ (' .target ') . css(“显示”,“没有一个”);不会改变你的.target {} CSS声明。相反,这里发生的是任何具有“target”类的元素现在看起来像这样:
<element class="target" style="display:none;"></element>
没有预先定义CSS样式规则会有什么副作用吗?一点儿也没有呢。
还有更好的办法吗?就性能而言,确实有!
如何提高性能?
不是直接修改每个元素的样式,而是可以预先定义一个新类,并使用addClass()(另一个jQuery方法)将其添加到匹配的元素中。
基于这个已经存在的比较css()和addClass()的JSPerf,我们可以看到addClass()实际上要快得多:
我们自己如何实现它呢?
首先,我们可以在新的CSS声明中添加:
.hidden {
display: none;
}
您的HTML将保持不变,这个预定义的类只是为以后使用而存在。
我们现在可以修改JavaScript来使用addClass():
$('.target').addClass('hidden');
当运行这段代码时,不是直接修改每个匹配的“目标”元素的style属性,这个新类现在将被添加:
<element class="target hidden"></element>
使用新的“hidden”类,此元素将继承CSS中声明的样式,并且您的元素将被设置为不再显示。
正如很多人提到的,是的,使用没有指定CSS的类是完全有效的,而不是把它们看作“CSS类”,你应该简单地认识到类和ID的语义分别是组和单独的元素。
我想插一句,因为我觉得在这个例子中,一个重要的点没有被提出。如果你曾经需要对可变长度的元素进行可视化操作(在这种情况下,你使用的是表行),那么认识到通过Javascript这样做的成本可能非常昂贵总是有意义的(例如,如果你有数千行)。
在这种情况下,假设我们知道列2总是有可能被隐藏(这是表的一个有意识的函数),那么设计一个CSS样式来处理这个用例是有意义的。
table.target-hidden .target { display: none; }
然后不是使用JS遍历DOM找到N个元素,我们只需要在一个(我们的表)上切换一个类。
$("table").addClass("target-hidden")
通过给表分配一个ID,这将更快,你甚至可以通过使用:n -child选择器引用列,这将进一步减少你的标记,但我不能评论效率。这样做的另一个原因是我讨厌内联样式,并将竭尽全力根除它!