评估 CSS 选择器 LTR 或 RTL 是不是更容易/更快?

Posted

技术标签:

【中文标题】评估 CSS 选择器 LTR 或 RTL 是不是更容易/更快?【英文标题】:Is it easier/faster to evaluate CSS selectors LTR or RTL?评估 CSS 选择器 LTR 或 RTL 是否更容易/更快? 【发布时间】:2011-05-07 00:20:37 【问题描述】:

给定一个类似的 CSS 选择器

ul > li a

从左到右还是从右到左评估它会更容易/更快吗? (我意识到“简单”和“更快”的答案可能不同。我想要两个答案)。我即将踏上其中一条道路,我不想走到一半然后意识到我选择了错误的道路:)

LTR:遍历文档中的所有元素,挑选出ul 的元素,然后检查它们的所有子元素是否有li,然后查看它们的后代元素是否有a

RTL:遍历文档中的所有元素,找到所有a,过滤掉没有li祖先的元素,如果确实有li祖先,检查如果其父级是 ul,如果不是,则删除该 a

此外,除了迭代所有元素之外,真的没有其他方法可以做到这一点吗?


我正在考虑查找元素的上下文,就像 jQuery 所做的那样,而不是应用样式的上下文。

【问题讨论】:

它只是一个普通的 ol' CSS2 选择器。没什么 3 关于它。只是说:P @BoltClock:哎呀...好点。我计划支持 CSS3,但我想这与这个特定问题无关。 【参考方案1】:

浏览器和 Sizzle 选择器 JS 引擎(用于 jQuery 和其他框架)使用从右到左匹配。

在大多数情况下,从右到左是最佳的遍历解决方案。

Sizzle 优化了以 ID 开头的选择器。它首先解析具有 ID 的元素。然后它将其用作进一步遍历的上下文。

如果你有选择器

#myID > ul a

Sizzle 会首先找到带有#myID 的元素,假设在这种情况下,从左到右更优化。

【讨论】:

Ick.. 如果它首先找到#myID,那么它有点混合 LTR 和 RTL,这......只是令人困惑。我可以先将所有#ID 加载到字典中,然后进行 RTL 解析,但对于 #ID 跳过遍历并检查字典。【参考方案2】:

这是每个设计和编程论坛上重复出现的问题之一。一个常见的例子也是这个帖子上的原始海报给出的例子:

ul > 丽一个

如果你遍历 ltr,你会找到所有 uls,然后是这些 uls 的所有 lis,然后是这些 lis 中的所有标签。考虑一下标记可能看起来像这样的事实:

<ul>
    <li>
        <a href="#">Click Here</a>
    </li>
</ul>

或者它可能看起来像:

<ul>
    <li>
        <span>
            <p>
                <div class="someuselessclass">
                    <span class="JunkClass">
                        <a href="#">Click Here</a>
                    </span>
                </div>
            </p>
        </span>
    </li>
</ul>

事实是,您不知道遍历需要走多远,并且在数千个这样的 LI 中可能有数千个这样的链接。在我看来,通过经验,浏览器构建者得出的结论是从右到左解析更快。

这是我的两分钱。

【讨论】:

真的吗?这么频繁出现?我想唯一对此感兴趣的人是那些编写库的人,例如 jQuery 或布局引擎。但无论如何......我在想可能有和ul一样多的a。但是让我们假设一下,ul 和 a 的数量相同,如果它没有祖先 li,RTL 必须一直检查到根,而从 UL 开始 LTR,它只需要检查向下几级以找到 A 或叶节点。哪个距离更远......仍然不确定。 但我猜你的意思是 LTR 它必须解析所有的 UL 和 LI,即使它的末尾没有 A,而 RTL 它只考虑我们知道的那些有一个A?但我认为这样做也是同样的问题......您正在遍历所有 As,然后找到祖先 LI,并且可能有也可能没有父 UL。 我还忘了添加第三个代码示例,其中包含 li 中的数十个其他节点,这表明如果您执行 LTR 遍历,则必须覆盖数千个节点,而不是执行 RTL 我最终还是选择了 RTL.... 我想我发现它更容易。 code.google.com/p/sharp-query/source/browse/trunk/XCSS3SE/…

以上是关于评估 CSS 选择器 LTR 或 RTL 是不是更容易/更快?的主要内容,如果未能解决你的问题,请参考以下文章

RTL和LTR抽屉根据用户语言在它们之间进行导航切换

动态更改引导网格方向( ltr 到 rtl 或反向)

Android:以编程方式更改整个应用布局方向

在 TextView 中使用区域设置 (ltr/rtl) 作为重力

在TextView中使用locale(ltr / rtl)作为重力

Laravel 5 - 多语言网站(LTR 和 RTL)