【问题标题】:Can I force jQuery to use Sizzle to evaluate a selector without using non-standard selectors?我可以强制 jQuery 使用 Sizzle 来评估选择器而不使用非标准选择器吗?
【发布时间】:2012-07-29 16:38:47
【问题描述】:

在现代浏览器中,jQuery 使用document.querySelectorAll() 来提高使用有效 CSS 选择器时的性能。如果浏览器不支持选择器或 document.querySelectorAll() 方法,它会退回到 Sizzle。

但是,在调试自定义选择器时,我希望始终使用 Sizzle 而不是本机实现。也就是说,我正在尝试提出:nth-last-child()one of the CSS3 selectors that are not supported by jQuery 的实现。由于现代浏览器原生支持此选择器,因此它的工作原理与链接问题中的描述相同。不过,正是这种行为干扰了我的自定义选择器的调试,所以我想避免它。

我可以使用的一个便宜的技巧是放入一个非标准的jQuery selector extension,从而可以说“使”选择器“无效”。例如,假设每个li:nth-last-child(2) 都是visible,我可以简单地将其放入,然后转为:

$('li:nth-last-child(2)').css('color', 'red');

进入这个:

$('li:nth-last-child(2):visible').css('color', 'red');

这会导致它始终由 Sizzle 评估。除此之外,这要求我对我的页面元素做出一个假设,这可能是真的,也可能不是。我真的不喜欢那样。更不用说,除非绝对必要,否则我一般不喜欢使用非标准选择器。

有没有办法在支持它的浏览器中跳过原生 document.querySelectorAll() 方法并强制 jQuery 使用 Sizzle 来评估选择器,最好 使用非标准选择器?很可能,这需要调用另一个方法而不是 $(),但它比选择器黑客 IMO 要好得多。

【问题讨论】:

标签: javascript jquery jquery-selectors sizzle


【解决方案1】:

您可以在 jQuery 加载之前将其设置为 null,因此它认为它不受支持:

document.querySelectorAll = null;
//load jquery, will trigger not supported branch
//Optionally restore QSA here (save a reference) if needed

这应该使this 评估为false

演示:http://jsbin.com/asipil/2/edit

注释掉null这一行并重新运行,你会看到它会变成红色。

【讨论】:

  • 又是一个非常明显的例子,其他人不得不向我指出。不敢相信我错过了 :) 我忘了提到我也更愿意不理会本机实现,但如果没有其他解决方案,那么我想这将不得不这样做。
  • 有效吗?浏览器是否允许覆盖这个属性,如果是,所有这些? edit: 似乎至少可以在 Chrome 中使用。
  • 我不相信你必须这样做,看我的回答。
  • +1 @Esailija 看起来在 1.9 中它正在工作...:-) jsbin.com/asipil/11/edit
【解决方案2】:

既然您是自己开发选择器的代码,您能否在开发周期内简单地给它一个自定义名称?也许给它你自己的供应商前缀或什么? -bolt-nth-last-child()

这样,你就会知道浏览器肯定不支持它,所以它应该总是使用 Sizzle。

完成开发周期后,您可以删除 -bolt- 前缀。

我知道这更像是一种变通方法,而不是问题的答案,但对我来说这似乎是最简单的解决方案。

【讨论】:

    【解决方案3】:

    看起来jQuery.find 默认发出嘶嘶声。这将使您免于通过将本机函数设置为 null 来破坏您的环境。

    https://github.com/jquery/jquery/blob/master/src/sizzle-jquery.js#L3

    所以您应该能够执行以下操作,并且它总是会发出嘶嘶声。

    $.find('li:nth-last-child(2)')
    

    【讨论】:

    • 如果document.querySelectorAll 测试评估为true,则Sizzle 在此分配之前已被覆盖。见查看源:code.jquery.com/jquery-1.7.2.js line 5093
    • 该行中引用的Sizzle 方法包含在回退到其内部实现之前的本机调用(我猜这是@Esailija 所指的覆盖实现)。开始here。我做了一个fiddle,确实,它显示:nth-last-child()工作,所以它仍在使用本机方法。
    • 您能指出它的区别所在吗?对querySelectorAll 的唯一引用是从1316 开始,如果断言失败,我看不到任何告诉它使用querySelectorAll 的东西。 github.com/jquery/sizzle/blob/master/sizzle.js#L1316
    • @travis 在该 github 文件的情况下 select 与 jQuery 文件中的 Sizzle 相同。您现在可以看到,如果 document.querySelectorAll 测试评估为 trueselect(即 jQuery 中的 Sizzle),将被使用本机查询选择器的版本覆盖。见这里:github.com/jquery/sizzle/blob/master/sizzle.js#L1370
    猜你喜欢
    • 1970-01-01
    • 2014-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多