从jQuery选择器中过滤元素

时间:2010-07-15 14:58:51

标签: javascript jquery

我有一个页面,它选择表单中的所有元素并将它们序列化为:

var filter = 'form :not([name^=ww],[id$=IDF] *,.tools *)';
var serialized = $(filter).serialize();

这是有效的,除非表格大约有600多个元素。然后用户得到javascript错误,说脚本运行缓慢,可能会使他们的浏览器无响应。然后它为他们提供了停止运行脚本的选项。

我试过单独运行过滤器,我尝试在选择器上使用.not,然后序列化它们,但我遇到了两个问题之一。要么运行得更快而没有错误,但也不会过滤元素,或者它会过滤元素并给我慢速脚本错误。

有什么想法吗?

3 个答案:

答案 0 :(得分:5)

有600多个元素,这将会变慢。您需要为Sizzle(jQuery的选择器引擎)提供一些优化机会。

首先,考虑一下jQuery可以使用本机支持的querySelectorAll方法(在现代浏览器中),如果您的选择器符合CSS3 spec(或至少达到目前支持的范围)浏览器)。

根据您的情况,这意味着只将一个简单选择器传递给:not而不是3(1个简单,2个复杂)。

form :not([name^=ww])

这会非常快......虽然你不喜欢不支持querySelectorAll的浏览器。

看看你的选择器,想想Sizzle与每个元素有多少关系。首先,它需要获取页面中的所有元素(您不是使用标记/ class / id预先限定 :not选择器)。然后,在每个元素上执行以下操作:

(假设如果检查结果为假则退出)

  1. 检查父母的祖先是nodeName.toLowerCase() form
  2. 检查它是否没有以name开头的ww属性(基本indexOf操作)。
  3. 检查它是否没有id属性以IDF结尾的祖先。 (昂贵的操作)
  4. 检查它没有包含class tools属性的祖先。
  5. 最后两个操作很慢。

    最好手动构建filter函数,如下所示:

    var jq = $([1]);
    $('form :input').filter(function(){
    
        // Re-order conditions so that
        // most likely to fail is at the top!
    
        jq[0] = this; // faster than constructing a new jQ obj
    
        return (
    
            !jq.closest('[id$=IDF]')[0]
                // this can be improved. Maybe pre-qualify
                // attribute selector with a tag name
    
            && !jq.closest('.tools')[0]
    
            && this.name.indexOf('ww') !== 0
    
        );
    
    });
    

    注意:该功能未经测试。希望你明白了......

答案 1 :(得分:1)

您是否可以将整个表单序列化并在后端进行过滤?另外,为什么 - 为什么表格会增长到600多个领域呢?

答案 2 :(得分:0)

使用:input选择器仅选择适用的元素..