在 jQuery 中使用 * 选择器将 CSS3PIE 与 Modernizr 一起应用

Posted

技术标签:

【中文标题】在 jQuery 中使用 * 选择器将 CSS3PIE 与 Modernizr 一起应用【英文标题】:Using * selector in jQuery to apply CSS3PIE with Modernizr 【发布时间】:2012-03-07 02:44:58 【问题描述】:

这篇博文的标题读作 webdev-hipster 就像一场野猫比赛中的紧身法兰绒围巾。对不起。

我不擅长脚本运行时优化,所以我想知道下面的函数调用在计算上会有多糟糕。我知道这对于大型网站来说并不实用,但是在我想使用它的地方,jQuery 调用将返回不超过六个对象,所以音量并不高。

 Modernizr.load(
    test: Modernizr.borderradius && Modernizr.boxshadow,
    nope: "_/js/polyfills/pie.js",
    complete: function()
        if(window.PIE)
            $('*').css('box-shadow').each(function() PIE.attach(this); );
            $('*').css('border-radius').each(function() PIE.attach(this); );
        
    
 );

谢谢大家。

【问题讨论】:

你想做什么?您的代码有一个错误 .css('box-shadow') 返回一个字符串,并且您将它用作 jQuery 对象。 @Shankar 你是对的。但这并不完全是一个错误:我没有仔细查看 $.css() - 我认为它更像 $.hasClass()。现在我发现我需要一个更复杂的 jQuery 语句来过滤结果。 【参考方案1】:

试试这个。

 Modernizr.load(
    test: Modernizr.borderradius && Modernizr.boxshadow,
    nope: "_/js/polyfills/pie.js",
    complete: function()
        if(window.PIE)
            $('*').each(function()
                var $this = $(this);
                //check if box-shadow or border-radius is applied
                if($this.css('box-shadow') || $this.css('border-radius'))
                    PIE.attach(this);
                
            );
        
    
 );

【讨论】:

@Evan - 根据您的评论,我为您提供了这个解决方案,希望对您有所帮助。 这太完美了!当您提交它时,我实际上是在这里输入基本相同的解决方案来“回答”自己,但事实证明我无论如何都无法做到这一点。向你的朋友致敬! 因为我在两个地方使用它所以缓存了它。如果你使用 $(this) 也可以。 我建议不要使用 * 作为根选择器,如果您知道您要定位的页面的哪个部分使用该部分或容器作为根选择器。 我想是的。我知道$('*') 是一根大棒,它首先提出了这个问题,但我想过滤不是那么糟糕吧?自然$('body') 将减少1/3 的选择,CSS 只会应用于文档的那部分。感谢您对此的帮助。【参考方案2】:

...jQuery 调用将返回不超过六个对象...

所以半打是六。其中四个将是htmlheadscriptbody。 :-) 页面上只有另外两个元素?

说真的,如果数量非常少,也没关系。不过,您希望将 $() 调用限制为仅对真正需要它的元素进行调用,而不是 $("*"),后者是一把大锤子。

如果你真的需要遍历整个文档,使用一个简单的递归下降函数:

function applyPie(element) 
    var node;
    for (node = element.firstChild; node; node = node.nextSibling) 
        if (node.nodeType === 1)  // 1 = element
            node.style.boxShadow = /* ...?... there's nothing in your jQuery call */;
            node.style.borderRadius = /* ...?... there's nothing in your jQuery call */;
            PIE.attach(node);
            applyPie(node);
        
    


applyPie(document.documentElement);

这会在除documentElement 之外的每个元素上调用PIE.attach。您可以使用nodeName(或tagName),这样您就不会将PIE 附加到htmlheadstyle 等。使用简单的递归下降函数可以避免在内存中创建大型平面数组,$("*") 就是这样做的。

【讨论】:

这些页面的 DOM 中还有很多元素。 “jQuery 调用”是指由 .css() 函数过滤的结果。我的逻辑是 jQuery 只能选择那些我应用了某些 CSS3 规则的元素,允许我保守地附加 PIE。 WRT 你的建议,它肯定会起作用,但我觉得有一种更有效的方法可以让 jQuery 选择器完成工作。 @Evan:您所做的不会根据这些属性过滤结果(正如您现在从 Shankar 知道的那样)。请注意您接受的答案,它会在您的页面 ($("*")) 上创建一个包含 all 元素的平面数组并循环遍历它;这可能是一个 very 大数组。此外,它然后使用css 来确定您在哪里应用了这些属性,但是正如css under-the-covers 使用getComputedStyle 等,不能保证当浏览器不返回任何内容时支持它。至少,最好使用递归下降函数而不是$("*") 感谢您的意见 T.J.不过,我会打赌 jQuery 的跨浏览器性能。为了便于维护和我们处理的对象数量有限,我认为 Shankar 的解决方案是***的。我会记住您的技术,但如果我必须在更大的站点上执行此操作,它确实具有性能优势,特别是因为它是使用核心 api 完成的!再次感谢。

以上是关于在 jQuery 中使用 * 选择器将 CSS3PIE 与 Modernizr 一起应用的主要内容,如果未能解决你的问题,请参考以下文章

jQuery中$符号的作用

在 jQuery each() 中显示一个唯一的选择器

jQuery 多日期选择器问题

使用 ASP.NET MVC C# 和引导日期选择器将不起作用

我可以使用啥 jQuery 选择器来匹配这些 HTML 元素(需要“:contains()”)?

为啥 jQuery 选择器只选择特定网站上的第一个层次结构元素?