2010-07-15 63 views
2

我有一个选择表单中所有的元素和序列化他们这样的页面:过滤器元件出了jQuery选择

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

这工作,除非形式得到周围600+元素。然后用户得到的JavaScript错误,说脚本运行缓慢,并可能使他们的浏览器无响应。然后它给他们停止运行脚本的选项。

我已经尝试单独运行过滤器,我试图使用.not在选择器上,然后序列化它们,但我碰到两个问题之一。它可以在没有错误的情况下运行得更快,但也不会过滤元素,也可以过滤元素并为我提供缓慢的脚本错误。

任何想法?

+2

*为什么,哦为什么*你会在HTML中有600多个输入元素!?!? – 2010-07-15 15:03:06

+0

你的问题不是选择器。重新设计你的页面,使其使用较少的输入字段。重新设计你的逻辑,以便它不需要在脚本中序列化数百个项目。具有较少输入字段的 – 2010-07-15 15:09:08

+0

不是一种选择。我不能详细说明,但这是设计 – 2010-07-15 15:16:07

回答

5

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

首先考虑的是jQuery可使用固有支持querySelectorAll方法(在现代的浏览器),如果你的选择与CSS3 spec(或至少是什么在浏览器中编辑器目前支援的范围内)的规定。

在你的情况下,这意味着只能通过一个简单选择器到:not而不是3(1简单,2复杂)。

form :not([name^=ww]) 

那会是相当快......虽然你不善待那些不支持querySelectorAll浏览器。

看看你的选择器,并考虑Sizzle与每个元素有多少关系。首先它需要获得页面内的所有元素(你不是预标准:not选择器与标记/类/ id)。然后,每个元素就可以执行以下操作:

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

  1. 检查家长有与formnodeName.toLowerCase()的祖先。
  2. 检查它是否具有ww(基本indexOf操作)开始的name属性。
  3. 检查它是否有一个id属性以IDF结尾的祖先。 (昂贵的操作)
  4. 检查它是否具有包含toolsclass属性的祖先。

最后两个操作很慢。

这可能是最好手动构建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尼斯分析。 – 2010-07-15 15:42:09

+0

哇,看起来不错!我会试一试并在此发布结果。谢谢。 – 2010-07-15 15:49:20

+0

我想补充一点,如果我能看到标记,我可以帮助优化这个。我仍然有关于它的问题......比如:有多少个[id $ = IDF]元素,并且它们都是不同的标签?他们没有办法给予同一个班级吗? – James 2010-07-15 15:59:05

1

你可能只是序列化整个表单,并在后端做你的过滤?另外,为什么 - 哦,为什么表单增长到600多个字段?

+0

这将工作,但我需要在做回发之前在序列化表单上做一些逻辑 – 2010-07-15 15:18:02

+0

嗯,我会尝试发回你需要执行的任何数据该逻辑返回请求,并让后端执行该操作。这样你就可以在整个表单上进行'serialize'操作,这应该是相当快的(例如,不在列表中,而是在一个表单元素上),然后在后端退出时简单地显示一个微调器。 – rfunduk 2010-07-15 15:33:41

0

使用:input选择,只选择适用的元素..

+0

我会试一试 – 2010-07-15 15:17:03

+0

@barlow,我想我的答案可能是错误的..我相信序列化只会选择':input'元素默认情况下......但jquery api网站目前停止并且无法验证.. – 2010-07-15 15:22:24