在DevTools中使用“配置文件”调试我的应用程序时,我发现“累积的DOM树的”不断积累。这些分离的节点具有保留树,其中大部分由checkContext函数组成(来自sizzle内部的jQuery-v1.10.1)。

我不确定如何进行此操作。这个结果什么意思?

最佳答案

这实际上是一个错误,Sizzle没有理由需要卡在上下文节点上,之所以这样做,是因为设置临时变量后并没有清除它。我提交了一个issue for it,对其进行了修复,运行了所有的Sizzle测试,并提出了请求请求。

如果要修补现有的jQuery或Sizzle副本:

  • 打开您的jQuery或Sizzle文件
  • 搜索matcherFromTokens函数
  • 在其中找到此代码(在顶部附近):
    matchers = [ function( elem, context, xml ) {
        return ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
            (checkContext = context).nodeType ?
                matchContext( elem, context, xml ) :
                matchAnyContext( elem, context, xml ) );
    } ];
    
  • return更改为var rv =,并在匿名函数的末尾添加checkContext = undefined;return rv;,例如:
    matchers = [ function( elem, context, xml ) {
        var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
            (checkContext = context).nodeType ?
                matchContext( elem, context, xml ) :
                matchAnyContext( elem, context, xml ) );
        // Release the context node (issue #299)
        checkContext = null;
        return ret;
    } ];
    

  • 注意:该代码将null分配给checkContext,因为显然这就是它们的样式。如果是我,我会改为分配undefined

    如果在拉取请求/合并过程中提出的修复程序有任何问题,我将更新答案。

    最好让Sizzle缓存选择器,因为jQuery使用带有事件委托(delegate)的已编译选择器,并且您不希望每次相关事件发生时都必须重新解析和重建匹配器函数,以便它可以确定元素是否存在匹配它。

    不幸的是,这并不是jQuery在编译选择器中保留元素的唯一位置。它在每个地方所做的工作都可能是可以使用修复程序的错误。我只有时间来追踪彼此,我也已经报告并修复了这个问题(在请求拉入请求之前):

    如果您搜索“可能复杂的伪”,则会为:not伪选择器找到它:
    pseudos: {
        // Potentially complex pseudos
        "not": markFunction(function( selector ) {
            // Trim the selector passed to compile
            // to avoid treating leading and trailing
            // spaces as combinators
            var input = [],
                results = [],
                matcher = compile( selector.replace( rtrim, "$1" ) );
    
            return matcher[ expando ] ?
                markFunction(function( seed, matches, context, xml ) {
                    var elem,
                        unmatched = matcher( seed, null, xml, [] ),
                        i = seed.length;
    
                    // Match elements unmatched by `matcher`
                    while ( i-- ) {
                        if ( (elem = unmatched[i]) ) {
                            seed[i] = !(matches[i] = elem);
                        }
                    }
                }) :
                function( elem, context, xml ) {
                    input[0] = elem;
                    matcher( input, null, xml, results );
                    return !results.pop();
                };
        }),
    

    问题出在条件运算符中:之后的函数中:
    function( elem, context, xml ) {
        input[0] = elem;
        matcher( input, null, xml, results );
        return !results.pop();
    };
    

    注意,它永远不会清除input[0]。解决方法:
    function( elem, context, xml ) {
        input[0] = elem;
        matcher( input, null, xml, results );
        // Don't keep the element (issue #299)
        input[0] = null;
        return !results.pop();
    };
    

    目前,这就是我所有的时间。

    07-28 07:44